731 lines
9.4 KiB
Markdown
731 lines
9.4 KiB
Markdown
|
|
KeyCapeSpecPac
|
|||
|
|
|
|||
|
|
*Implementation guidane for keycape*
|
|||
|
|
|
|||
|
|
Below is the **Normative Specification Pack v0.1** for **Keycape**.
|
|||
|
|
This version is structured so that a **coding agent can implement it**.
|
|||
|
|
|
|||
|
|
The pack contains the seven components we discussed:
|
|||
|
|
|
|||
|
|
1. Normative Specification
|
|||
|
|
2. Canonical Identity Schema
|
|||
|
|
3. Canonical LDAP Schema + Validator Rules
|
|||
|
|
4. Error Taxonomy
|
|||
|
|
5. Telemetry Schema
|
|||
|
|
6. Migration Contract
|
|||
|
|
7. Acceptance Test Matrix
|
|||
|
|
|
|||
|
|
This document is written **normatively where required** (MUST / SHOULD / MAY).
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# Keycape Normative Specification Pack v0.1
|
|||
|
|
|
|||
|
|
**Project:** NetKingdom
|
|||
|
|
**Component:** Keycape
|
|||
|
|
**Status:** Normative Draft
|
|||
|
|
**Audience:** Developers, architecture engineers, coding agents
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 1. Normative Specification
|
|||
|
|
|
|||
|
|
## 1.1 Purpose
|
|||
|
|
|
|||
|
|
Keycape is a **lightweight implementation of the NetKingdom IAM Profile**.
|
|||
|
|
|
|||
|
|
Keycape provides:
|
|||
|
|
|
|||
|
|
* a stable **OIDC-based IAM contract**
|
|||
|
|
* a **lightweight runtime implementation**
|
|||
|
|
* strict **profile enforcement**
|
|||
|
|
* **telemetry** about demanded IAM functionality
|
|||
|
|
* **automated migration readiness** for Keycloak replacement
|
|||
|
|
|
|||
|
|
Keycape is **not a Keycloak clone**.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1.2 Architectural Role
|
|||
|
|
|
|||
|
|
Keycape is the **external IAM contract provider** in lightweight mode.
|
|||
|
|
|
|||
|
|
Applications interact only with the **NetKingdom IAM Profile**.
|
|||
|
|
|
|||
|
|
Keycape internally orchestrates:
|
|||
|
|
|
|||
|
|
| Component | Responsibility |
|
|||
|
|
| ----------- | --------------------- |
|
|||
|
|
| Authelia | OIDC provider backend |
|
|||
|
|
| LLDAP | identity directory |
|
|||
|
|
| privacyIDEA | MFA authority |
|
|||
|
|
|
|||
|
|
Expanded mode replaces Keycape with **Keycloak**.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1.3 Supported Protocol
|
|||
|
|
|
|||
|
|
Keycape MUST implement:
|
|||
|
|
|
|||
|
|
**OpenID Connect 1.0**
|
|||
|
|
|
|||
|
|
Using:
|
|||
|
|
|
|||
|
|
**Authorization Code Flow + PKCE**
|
|||
|
|
|
|||
|
|
Reference model:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Application
|
|||
|
|
|
|
|||
|
|
v
|
|||
|
|
Keycape (profile contract)
|
|||
|
|
|
|
|||
|
|
v
|
|||
|
|
Authelia + LLDAP + privacyIDEA
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Expanded mode:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Application
|
|||
|
|
|
|
|||
|
|
v
|
|||
|
|
Keycloak
|
|||
|
|
|
|
|||
|
|
v
|
|||
|
|
LDAP + privacyIDEA
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1.4 Mandatory Endpoints
|
|||
|
|
|
|||
|
|
Keycape MUST expose the following endpoints.
|
|||
|
|
|
|||
|
|
| Endpoint | Required |
|
|||
|
|
| ----------------------------------- | -------- |
|
|||
|
|
| `/.well-known/openid-configuration` | YES |
|
|||
|
|
| `/authorize` | YES |
|
|||
|
|
| `/token` | YES |
|
|||
|
|
| `/jwks` | YES |
|
|||
|
|
| `/userinfo` | OPTIONAL |
|
|||
|
|
| `/logout` | OPTIONAL |
|
|||
|
|
| `/introspect` | OPTIONAL |
|
|||
|
|
|
|||
|
|
Discovery MUST correctly advertise supported features.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1.5 Authentication Flow
|
|||
|
|
|
|||
|
|
Supported flow:
|
|||
|
|
|
|||
|
|
Authorization Code + PKCE
|
|||
|
|
|
|||
|
|
Requirements:
|
|||
|
|
|
|||
|
|
Client MUST supply:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
client_id
|
|||
|
|
redirect_uri
|
|||
|
|
response_type=code
|
|||
|
|
scope=openid
|
|||
|
|
code_challenge
|
|||
|
|
code_challenge_method=S256
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Keycape MUST validate:
|
|||
|
|
|
|||
|
|
* redirect URI
|
|||
|
|
* client configuration
|
|||
|
|
* PKCE challenge
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1.6 Token Requirements
|
|||
|
|
|
|||
|
|
Tokens MUST be JWT.
|
|||
|
|
|
|||
|
|
Minimum claims:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
iss
|
|||
|
|
sub
|
|||
|
|
aud
|
|||
|
|
exp
|
|||
|
|
iat
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Optional claims:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
preferred_username
|
|||
|
|
email
|
|||
|
|
groups
|
|||
|
|
roles
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Signature MUST use:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
RS256
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
JWKS MUST be available at `/jwks`.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1.7 Client Model
|
|||
|
|
|
|||
|
|
Client registration is **static** in v0.1.
|
|||
|
|
|
|||
|
|
Client fields:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
client_id
|
|||
|
|
client_secret (optional for public)
|
|||
|
|
redirect_uris[]
|
|||
|
|
allowed_scopes[]
|
|||
|
|
allowed_grants[]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Dynamic registration is **NOT allowed**.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1.8 MFA Behavior
|
|||
|
|
|
|||
|
|
MFA enforcement is delegated to **privacyIDEA**.
|
|||
|
|
|
|||
|
|
Keycape MUST:
|
|||
|
|
|
|||
|
|
* detect MFA requirement
|
|||
|
|
* enforce MFA before token issuance
|
|||
|
|
* fail authentication if MFA fails
|
|||
|
|
|
|||
|
|
Keycape MUST NOT implement MFA logic itself.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1.9 Claims Model
|
|||
|
|
|
|||
|
|
Claims MUST follow the **Canonical Identity Model**.
|
|||
|
|
|
|||
|
|
Mapping example:
|
|||
|
|
|
|||
|
|
| Claim | Source |
|
|||
|
|
| ------------------ | ---------------------- |
|
|||
|
|
| sub | canonical user ID |
|
|||
|
|
| preferred_username | LDAP uid |
|
|||
|
|
| email | LDAP mail |
|
|||
|
|
| groups | LDAP groupOfNames |
|
|||
|
|
| roles | canonical role mapping |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 2. Canonical Identity Model
|
|||
|
|
|
|||
|
|
The canonical model is the **source of truth** for identities.
|
|||
|
|
|
|||
|
|
All provisioning, tests, and migrations derive from it.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2.1 Canonical Entities
|
|||
|
|
|
|||
|
|
Entities:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
User
|
|||
|
|
Group
|
|||
|
|
Role
|
|||
|
|
Client
|
|||
|
|
Membership
|
|||
|
|
MFAEnrollment
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2.2 Canonical User Schema
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
User:
|
|||
|
|
id: string
|
|||
|
|
username: string
|
|||
|
|
displayName: string
|
|||
|
|
email: string
|
|||
|
|
enabled: boolean
|
|||
|
|
groups:
|
|||
|
|
- group_id
|
|||
|
|
roles:
|
|||
|
|
- role_id
|
|||
|
|
attributes:
|
|||
|
|
key: value
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2.3 Canonical Group Schema
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
Group:
|
|||
|
|
id: string
|
|||
|
|
name: string
|
|||
|
|
description: string
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2.4 Canonical Client Schema
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
Client:
|
|||
|
|
client_id: string
|
|||
|
|
display_name: string
|
|||
|
|
redirect_uris:
|
|||
|
|
- uri
|
|||
|
|
allowed_scopes:
|
|||
|
|
- scope
|
|||
|
|
grant_types:
|
|||
|
|
- authorization_code
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2.5 Canonical MFA Schema
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
MFAEnrollment:
|
|||
|
|
user_id: string
|
|||
|
|
provider: privacyidea
|
|||
|
|
state: enabled
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 3. Canonical LDAP Schema
|
|||
|
|
|
|||
|
|
The canonical LDAP schema expresses the identity model in LDAP.
|
|||
|
|
|
|||
|
|
This ensures portability across:
|
|||
|
|
|
|||
|
|
* LLDAP
|
|||
|
|
* OpenLDAP
|
|||
|
|
* 389DS
|
|||
|
|
* Active Directory
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3.1 LDAP Tree Layout
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
dc=netkingdom,dc=local
|
|||
|
|
|
|||
|
|
ou=users
|
|||
|
|
ou=groups
|
|||
|
|
ou=clients
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3.2 User Entry
|
|||
|
|
|
|||
|
|
Object classes:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
inetOrgPerson
|
|||
|
|
organizationalPerson
|
|||
|
|
person
|
|||
|
|
top
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Attributes:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
uid
|
|||
|
|
cn
|
|||
|
|
sn
|
|||
|
|
mail
|
|||
|
|
memberOf
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Example:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
dn: uid=alice,ou=users,dc=netkingdom,dc=local
|
|||
|
|
uid: alice
|
|||
|
|
cn: Alice
|
|||
|
|
sn: Example
|
|||
|
|
mail: alice@example.com
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3.3 Group Entry
|
|||
|
|
|
|||
|
|
Object classes:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
groupOfNames
|
|||
|
|
top
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Attributes:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
cn
|
|||
|
|
member
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 4. LDAP Schema Validator
|
|||
|
|
|
|||
|
|
Validator MUST verify:
|
|||
|
|
|
|||
|
|
### Structural Rules
|
|||
|
|
|
|||
|
|
* valid DN structure
|
|||
|
|
* required attributes present
|
|||
|
|
* no unknown attributes
|
|||
|
|
* valid group memberships
|
|||
|
|
|
|||
|
|
### Semantic Rules
|
|||
|
|
|
|||
|
|
* referenced users exist
|
|||
|
|
* groups are not cyclic
|
|||
|
|
* usernames unique
|
|||
|
|
* email format valid
|
|||
|
|
|
|||
|
|
Validator MUST run in:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
CI
|
|||
|
|
Provisioning
|
|||
|
|
Migration
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 5. Error Taxonomy
|
|||
|
|
|
|||
|
|
Keycape MUST implement structured errors.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5.1 Error Types
|
|||
|
|
|
|||
|
|
### feature_not_supported_by_profile
|
|||
|
|
|
|||
|
|
Requested functionality outside the profile.
|
|||
|
|
|
|||
|
|
Example:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
dynamic_client_registration
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### available_in_keycloak_mode_only
|
|||
|
|
|
|||
|
|
Feature exists only in expanded mode.
|
|||
|
|
|
|||
|
|
Example:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
identity_broker
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### rejected_for_profile_safety
|
|||
|
|
|
|||
|
|
Feature intentionally blocked.
|
|||
|
|
|
|||
|
|
Example:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
wildcard_redirect_uri
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### invalid_profile_usage
|
|||
|
|
|
|||
|
|
Client misused the profile.
|
|||
|
|
|
|||
|
|
Example:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
missing_pkce
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5.2 Error Format
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
{
|
|||
|
|
"error": "feature_not_supported_by_profile",
|
|||
|
|
"description": "...",
|
|||
|
|
"feature": "identity_broker"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 6. Telemetry Schema
|
|||
|
|
|
|||
|
|
Keycape MUST emit telemetry events.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6.1 Telemetry Event Types
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
auth_start
|
|||
|
|
auth_success
|
|||
|
|
auth_failure
|
|||
|
|
token_issued
|
|||
|
|
unsupported_feature
|
|||
|
|
invalid_request
|
|||
|
|
migration_event
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6.2 Telemetry Fields
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"timestamp": "...",
|
|||
|
|
"client_id": "...",
|
|||
|
|
"endpoint": "...",
|
|||
|
|
"feature": "...",
|
|||
|
|
"result": "...",
|
|||
|
|
"error_type": "...",
|
|||
|
|
"scopes": [],
|
|||
|
|
"grant_type": "...",
|
|||
|
|
"environment": "...",
|
|||
|
|
"trace_id": "..."
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6.3 Telemetry Outputs
|
|||
|
|
|
|||
|
|
Telemetry MUST support:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
logs
|
|||
|
|
metrics
|
|||
|
|
dashboards
|
|||
|
|
analysis
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 7. Migration Contract
|
|||
|
|
|
|||
|
|
Migration must support two dimensions.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7.1 IAM Migration
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Keycape → Keycloak
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Requirements:
|
|||
|
|
|
|||
|
|
* same issuer behavior
|
|||
|
|
* same claims
|
|||
|
|
* same scopes
|
|||
|
|
* same client behavior
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7.2 Directory Migration
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
LLDAP → Full LDAP
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Supported targets:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
OpenLDAP
|
|||
|
|
389 Directory Server
|
|||
|
|
Active Directory
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Migration MUST include:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
users
|
|||
|
|
groups
|
|||
|
|
memberships
|
|||
|
|
attributes
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 8. Replacement Testing
|
|||
|
|
|
|||
|
|
Replacement must be continuously verified.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8.1 Scenario A — Lightweight
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
LLDAP + Authelia + Keycape
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Run all profile tests.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8.2 Scenario B — IAM Replacement
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Keycloak + same directory
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Run same tests.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8.3 Scenario C — Full Expansion
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
LLDAP → LDAP
|
|||
|
|
Keycloak
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Run tests again.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8.4 Scenario D — Negative Tests
|
|||
|
|
|
|||
|
|
Attempt:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
unsupported scopes
|
|||
|
|
dynamic clients
|
|||
|
|
wildcard redirects
|
|||
|
|
identity brokering
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Verify errors and telemetry.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 9. Acceptance Criteria
|
|||
|
|
|
|||
|
|
Replacement is successful if:
|
|||
|
|
|
|||
|
|
* apps continue to work
|
|||
|
|
* claims remain stable
|
|||
|
|
* login flow unchanged
|
|||
|
|
* migration data valid
|
|||
|
|
* telemetry preserved
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 10. Security Requirements
|
|||
|
|
|
|||
|
|
Keycape MUST enforce:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
strict redirect URI validation
|
|||
|
|
PKCE mandatory
|
|||
|
|
no dynamic client registration
|
|||
|
|
JWT signing via standard library
|
|||
|
|
no custom crypto
|
|||
|
|
issuer consistency
|
|||
|
|
short token lifetime
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 11. Implementation Requirements
|
|||
|
|
|
|||
|
|
Keycape SHOULD be implemented in:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Go or Rust
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Key requirements:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
stateless
|
|||
|
|
small memory footprint
|
|||
|
|
simple deployment
|
|||
|
|
clear logging
|
|||
|
|
structured telemetry
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 12. Recommended Repository Structure
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
keycape/
|
|||
|
|
├── spec/
|
|||
|
|
│ ├── iam-profile.md
|
|||
|
|
│ ├── canonical-model.yaml
|
|||
|
|
│ ├── ldap-schema.yaml
|
|||
|
|
│
|
|||
|
|
├── validator/
|
|||
|
|
│ └── ldap-validator
|
|||
|
|
│
|
|||
|
|
├── adapters/
|
|||
|
|
│ ├── authelia
|
|||
|
|
│ ├── lldap
|
|||
|
|
│ └── privacyidea
|
|||
|
|
│
|
|||
|
|
├── server/
|
|||
|
|
│ ├── oidc
|
|||
|
|
│ ├── telemetry
|
|||
|
|
│ └── errors
|
|||
|
|
│
|
|||
|
|
├── migration/
|
|||
|
|
│ ├── lldap-to-ldap
|
|||
|
|
│ └── keycape-to-keycloak
|
|||
|
|
│
|
|||
|
|
└── tests/
|
|||
|
|
├── profile
|
|||
|
|
├── migration
|
|||
|
|
└── negative
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 13. Next Step
|
|||
|
|
|
|||
|
|
The next step is creating the **Keycape Implementation Workplan**.
|
|||
|
|
|
|||
|
|
This will include:
|
|||
|
|
|
|||
|
|
* system architecture
|
|||
|
|
* internal modules
|
|||
|
|
* adapter design
|
|||
|
|
* telemetry pipeline
|
|||
|
|
* coding-agent instructions
|
|||
|
|
* milestone roadmap
|
|||
|
|
* estimated code size (~15–20k lines)
|
|||
|
|
|
|||
|
|
If you want, I can generate that next.
|
|||
|
|
|
|||
|
|
|
|||
|
|
xxx
|