Document actual capabilities and assess scope against intent

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06e87-e039-7ed2-b85c-20ad37f8a21b
This commit is contained in:
tegwick 2026-09-05 01:27:16 +02:00
parent b989de4e90
commit 30fa8570aa
3 changed files with 394 additions and 89 deletions

173
SCOPE.md
View file

@ -1,115 +1,110 @@
# SCOPE
> This file helps you quickly understand what this repository is about,
> when it is relevant, and when it is not.
> It is intentionally lightweight and may be incomplete.
Reviewed 2026-09-05 against source revision `b989de4`.
---
## Purpose and boundary
## One-liner
KeyCape is Go identity **Tooling** for NetKingdom's lightweight IAM deployment.
It runs its own OIDC-style issuer, uses Authelia for upstream browser
authentication, reads identities from LLDAP, and delegates factor checks to
privacyIDEA. It also provides caller authentication commands, directory snapshot
validation, and migration artifact generators.
Lightweight IAM implementation of the NetKingdom IAM Profile — orchestrates Authelia, LLDAP, and privacyIDEA to provide OIDC/PKCE authentication as a drop-in Keycloak alternative.
It issues identity, role, scope and assurance claims. Resource authorization
belongs to access-engine and consuming services; secret custody and OpenBao
policy/token enforcement belong to their platform owners. The implemented subset
supports NetKingdom integrations, but complete profile conformance and drop-in
Keycloak interchangeability are not established.
---
## Implemented capabilities
## Core Idea
| Surface | What the current source provides |
| --- | --- |
| Issuer HTTP API | Discovery, `/authorize` and its callback/registration-return routes, `/token`, `/jwks`, `/userinfo`, local `/logout`, and `/healthz`. |
| Human authentication | Authorization code with S256 PKCE, exact registered redirects, scope allow-lists, Authelia login, privacyIDEA MFA challenges, client-specific assurance requirements, browser session reuse, step-up/fresh-login handling, and configured registration/enrollment handoffs. |
| Service authentication | Static confidential `client_credentials` clients authenticated with form-encoded `client_secret_basic`; configured subject, tenant, roles, scopes and per-client token lifetime. Secrets are resolved from environment references at startup. |
| Tokens and identity | Locally signed RS256 JWTs; configurable access-token resource audience while ID tokens retain the client audience; human/service principal types, tenant, groups, roles, scope and assurance claims. UserInfo resolves canonical directory subjects and filters profile/email/groups by scope. |
| Caller commands | `keycape login` for public-client browser PKCE login and `keycape service-token` for service exchange. HTTPS discovery/JWKS verification and private JSON token-file delivery outside Git; no token output on stdout. |
| Validation and migration | Canonical snapshot checks; LLDAP user/group/membership export; basic Keycloak realm JSON; LDIF generation for OpenLDAP, 389 Directory Server and AD targets. These generate artifacts rather than execute a complete migration. |
| Diagnostics and packaging | Structured authentication/enforcement/migration events, a process health response, Go build/test/vet targets, a container containing the KeyCape binary, and development/CI scaffolding. |
NetKingdom applications target the "NetKingdom IAM Profile" — a versioned OIDC/PKCE contract. KeyCape implements that profile in lightweight mode (Authelia + LLDAP + privacyIDEA) with intentional constraints: no implicit flow, no wildcard redirects, no dynamic client registration. The same profile is implemented in expanded mode by Keycloak, so applications can migrate between modes without code changes.
## Material limits
---
- Client registrations, service secrets and the signing key are loaded at startup.
Login, authorization and handoff state are process-local. There is no shared
session store, general refresh-token flow, token introspection/revocation API,
or automatic signing-key/client-secret rotation service. Logout clears the
local KeyCape session, not every upstream or downstream session/token.
- The optional tenant-engine `tenant_roles` adapter and handler support exist,
but the server entry point does not configure them. That claim is not an
enabled capability of the stock executable.
- The Keycloak CLI exports users/groups through the basic transformer and has
no client-list input. Library-level client mapping does not preserve the full
current service-identity, audience, tenant/role, MFA and lifetime contract.
Password and MFA credential migration is not supplied.
- Snapshot validation is a limited Go rule set, not full machine-readable schema
enforcement. The canonical YAML model and discovery metadata lag newer runtime
capabilities. Protocol hardening gaps remain; see the assessment below.
- Tests cover local handlers, adapters, transformations and CLI protocol behavior.
They do not establish complete replacement against a running Keycloak/full-LDAP
stack. The Scenario B/C shell harnesses are incomplete.
- The server listens on HTTP; HTTPS termination is deployment-owned.
`/healthz` reports process status without probing dependencies. Development
Compose needs configuration/key material absent from the checkout. Production
deployment and custody are external; a source implementation or example client
fragment does not prove live registration or consumer cutover.
- Approval-client provisioning, coordinated Qonto rotation, native consumer
handoffs and notification receipt closure remain open in KEY-WP-0009/0013/0014.
## In Scope
## Deliberate exclusions
- OIDC profile endpoints (discovery, authorization, token, JWKS, userinfo) per NetKingdom IAM Profile
- Canonical identity model: users, groups, clients, MFA
- Claim normalization across Authelia/LLDAP/privacyIDEA backend quirks
- Profile enforcement with structured error taxonomy (no silent emulation of unsupported features)
- Telemetry for unsupported-feature requests
- Migration tooling: LLDAP export, Keycloak import, LDIF generation
- LDAP schema validation
- Full acceptance test suite (profile baseline, migration scenarios, negative tests)
General-purpose IAM, dynamic client registration, implicit/password grants,
wildcard redirects, arbitrary identity brokering, resource authorization policy,
OpenBao credential custody, and Keycloak operations are outside this repository's
ownership. Registration/enrollment handoffs do not implement user provisioning
or factor enrollment themselves.
---
## Entry points and verification
## Out of Scope
Run the issuer with `keycape --config PATH`; `keycape server` and
`keycape migrate` are not implemented subcommands. Caller commands are
`keycape login` and `keycape service-token`.
- General-purpose IAM (profile-specific only; no out-of-profile extensions)
- Dynamic client registration
- Implicit flow
- Wildcard redirect URIs
- Identity brokering beyond OIDC
- Keycloak operations (KeyCape is the lightweight alternative, not a Keycloak wrapper)
Separate binaries under `src/cmd/` are `validator`, `lldap-export`,
`keycape-to-keycloak`, and `lldap-to-ldap`. `make -C src build` places binaries in
root `bin/`; the container packages only `keycape`. Tests live under `src/tests/`
and alongside packages in `src/internal/`.
---
`make test`, `make lint` (Go vet), `make build`, and `make contract-test` are the
root checks. The capability-contract check requires the sibling NetKingdom
validator. These checks passed for the reviewed revision in the preceding
implementation session; the scope assessment is a source/documentation review.
## Relevant When
Use this repo for its bounded issuer, caller JWT acquisition, identity adapters
and migration preparation. Consult [INTENT.md](INTENT.md) for the architectural
target, [native authentication](docs/native-authentication.md) for caller
constraints, and the [scope/intent assessment](history/2026-09-05-011726-scope-intent-assessment.md)
for evidence, priorities and remaining gaps.
- Deploying NetKingdom IAM in lightweight mode (no Keycloak license/resources needed)
- Applications need OIDC authentication with MFA in a constrained environment
- Migrating from lightweight (KeyCape) to expanded (Keycloak) mode
- Validating LDAP schema or generating migration artifacts
---
## Not Relevant When
- Expanded-mode Keycloak is already running (applications use the same profile; no code changes needed)
- Need out-of-profile IAM features (dynamic client registration, implicit flow, etc.)
- Non-NetKingdom OIDC deployments
---
## Current State
- Status: stable (v0.1 complete)
- Implementation: complete — all 23 workplan tasks implemented and tested
- Stability: high — profile-constrained; no silent failures; acceptance tests passing
- Usage: internal NetKingdom stack; replaces Keycloak in lightweight deployments
---
## How It Fits
- Upstream dependencies: Authelia (OIDC provider/sessions), LLDAP (identity directory), privacyIDEA (MFA)
- Downstream consumers: all NetKingdom applications; net-kingdom (parent domain)
- Often used with: net-kingdom (SSO/MFA workplan), railiance (deployed on Railiance infrastructure)
---
## Terminology
- Preferred terms: NetKingdom IAM Profile, lightweight mode, expanded mode, profile enforcement, canonical model
- Also known as: "KeyCape", "key-cape"
- Potentially confusing terms: "lightweight mode" = KeyCape stack; "expanded mode" = Keycloak stack; both implement the same OIDC profile
---
## Related / Overlapping
- `net-kingdom` — parent platform domain; KeyCape is the lightweight IAM implementation of its IAM Profile
---
## Provided Capabilities
## Provided capabilities
```capability
type: security
title: OIDC/PKCE authentication (lightweight mode)
description: Provides OIDC/PKCE endpoints conforming to the NetKingdom IAM Profile via Authelia + LLDAP + privacyIDEA — a drop-in Keycloak alternative for constrained environments.
keywords: [oidc, pkce, authentication, iam, sso, authelia, lldap, mfa, identity]
title: Bounded OIDC and service-token issuance
description: Implements static-client browser PKCE and client-credentials authentication with RS256 identity claims through Authelia, LLDAP and privacyIDEA; complete Keycloak interchangeability remains unproven.
keywords: [oidc, pkce, authentication, iam, sso, mfa, identity, service-token]
```
```capability
type: security
title: Identity migration tooling
description: Migrate identities between lightweight (KeyCape) and expanded (Keycloak) IAM modes — LLDAP export, Keycloak import, LDIF generation.
keywords: [migration, identity, lldap, keycloak, ldif, iam]
title: Verified caller JWT acquisition
description: Provides native browser login and service-token exchange commands with HTTPS discovery, JWKS verification and private token-file delivery.
keywords: [oidc, pkce, jwt, cli, authentication, jwks]
```
---
## Getting Oriented
- Start with: `wiki/KeyCapeSpecification_v0.1.md` (architecture and design intent)
- Key files / directories: `wiki/KeyCapeSpecificationPack_v0.1.md` (normative spec), `src/cmd/` (binary entrypoints), `src/internal/` (implementation), `tests/` (acceptance suite)
- Entry points: `keycape server` binary; `keycape migrate` for migration tooling
```capability
type: security
title: Directory validation and migration artifact generation
description: Checks canonical snapshots and produces LLDAP exports, basic Keycloak realm JSON and target-specific LDIF; does not perform or prove a complete live migration.
keywords: [migration, identity, lldap, keycloak, ldif, validation]
```

View file

@ -0,0 +1,283 @@
# KeyCape scope against intent — 2026-09-05
Assessment timestamp: **2026-09-05 01:17:26 CEST (+02:00)**.
Source baseline: **b989de4e90248ff0782a3e99bc12a6d0c01487a4**.
Inputs: [INTENT](../INTENT.md), the previous SCOPE, implementation, tests,
build/operational scaffolding, and open workplans. Result: updated
[SCOPE](../SCOPE.md). INTENT is unchanged.
## Assessment
KeyCape substantially implements its identity-tooling purpose: it is a real
issuer with browser and service authentication, identity adapters, MFA policy
handling and caller commands. Its ownership boundary is consistent with INTENT:
it produces identity claims and delegates resource authorization and custody.
The stronger maturity claims are not established. “Strict” complete profile
conformance, stable identity through replacement, “seamless migration,” and
interchangeability without application changes exceed current implementation and
proof. The original 23-task workplan's completion is historical delivery evidence,
not evidence that every current contract, migration path or operational need is
complete. The accurate posture is **an implemented lightweight authentication
subset with tested local behavior and significant conformance, migration and
operational gaps**.
## Method and evidence limits
This is a source and documentation assessment, not a new live security audit or
migration rehearsal. The preceding implementation session at this baseline passed
`make test`, `make lint`, `make build` and `make contract-test`. No code changed in
this assessment and those checks were not rerun solely for wording changes.
Links and source claims were checked directly. Passing tests describe the covered
behavior; they do not establish the missing properties below.
Deployment observations in KEY-WP-0013 are earlier, explicitly dated evidence;
no fresh rollout, secret read, production token exchange or Keycloak migration
was performed here. Native caller behavior was tested locally, not certified as
a completed live consumer handoff. Findings marked as static risks need focused
regression tests before claiming exploitability or remediation.
## Alignment with INTENT
| INTENT commitment | Assessment | Evidence and limit |
| --- | --- | --- |
| Lightweight authentication Tooling | Substantially implemented | [Server composition](../src/cmd/keycape/main.go), [OIDC handlers](../src/internal/server/oidc/) and [adapters](../src/internal/adapters/). KeyCape signs its own tokens; it is more than a packaged reverse proxy. |
| Versioned, implementation-independent contract | Partial | Runtime supports newer service/audience policy than the v0.1 machine model and discovery metadata describe (G02). |
| Strong constraints and explicit rejection | Partial | Exact redirects, PKCE, scope checks, client-secret validation and [enforcement middleware](../src/internal/server/errors/enforcement.go) exist. Important validation and code-consumption boundaries remain incomplete (G01). |
| Canonical identity normalization | Partial | LDAP identities and group-derived tenant/roles are mapped. Directory portability, complete export and schema enforcement remain limited (G03/G05/G06). |
| Complete migration and interchangeable modes | Not demonstrated | Basic transforms and fixture tests exist. Current identity/client policy is not preserved end to end and live replacement harnesses are incomplete (G03/G04). |
| Deterministic, testable behavior | Strong local coverage; operational limits | Handler and CLI tests exercise actual local protocol code. Shared state, dependency readiness, complete exports and live backend replacement are not demonstrated (G04/G05/G08). |
| Minimal, secure, operationally efficient deployment | Partial | Small Go/container implementation exists; no resource benchmark or production-readiness certification was established. Bootstrap scaffolding and custody lifecycle need work (G08/G09/G10). |
| Authentication without resource authorization ownership | Aligned in scope | Claim issuance and local client/MFA rules are authentication policy; resource decisions remain with access-engine/consumers. This does not prove that every estate caller follows the engine-only integration rule. |
## Gaps and closure criteria
### G01 — Protocol trust and authorization-code consumption need hardening
**Priority: high. Kind: implementation gap / static security risk.**
[TokenHandler](../src/internal/server/oidc/token.go) validates PKCE, client ID and
scopes, but the authorization-code path does not authenticate confidential
clients or compare the submitted redirect URI with the stored one. Grant-type
eligibility is explicitly enforced on the service path, not equivalently on the
browser path. [SessionStore](../src/internal/server/oidc/session.go) retrieves a
code and deletes it in separate operations after signing; simultaneous requests
can reach the same session before deletion. This is not atomic single-use
consumption.
[UserInfo](../src/internal/server/oidc/userinfo.go) verifies an RSA signature and
expiry, but its `Issuer` field is unused in verification and the helper does not
validate the JOSE header algorithm, audience or token purpose. It cannot claim
the same verification contract as the new caller CLI.
The [Authelia adapter](../src/internal/adapters/authelia/adapter.go) deliberately
decodes upstream ID-token claims without signature verification and does not
validate their issuer/audience/expiry. Its comment assumes a trusted TLS service
boundary; the configuration permits internal HTTP endpoints. This is an explicit
trust assumption, not independent provider-token verification.
**Close when:** the accepted profile defines these bindings and trust boundaries;
implementation enforces them; negative tests cover confidential clients,
redirect/grant mismatch, issuer/token-purpose mismatch and concurrent code reuse.
Validate upstream provider tokens or explicitly establish and test the chosen
transport/trust contract. This assessment does not claim a demonstrated attack.
### G02 — Machine-readable contract and discovery lag the runtime
**Priority: high. Kind: contract drift.**
[spec/canonical-model.yaml](../spec/canonical-model.yaml) restricts grants to
`authorization_code`, requires redirect URIs for every client, and omits newer
service subject, tenant, audience, lifetime and MFA/handoff policy fields present
in [domain/model.go](../src/internal/domain/model.go) and
[config.go](../src/internal/config/config.go). Both the YAML and Go comments claim
to be the source of truth, without a demonstrated generation/conformance link.
[Discovery](../src/internal/server/oidc/discovery.go) advertises both grants but
uses a fixed basic scope/claim list that omits newer core claims and configured
resource scopes. It is not a complete inventory of the current profile surface.
**Close when:** select a canonical version, reconcile schema/runtime/discovery,
and add executable compatibility checks for human and service registrations.
Distinguish required profile claims from optional discovery metadata rather than
assuming every omission has the same protocol impact.
### G03 — Migration does not preserve the current authentication contract
**Priority: high. Kind: implementation gap.**
The [Keycloak CLI](../src/cmd/keycape-to-keycloak/main.go) calls `Transform`, which
passes no clients. Only the library's `TransformWithClients` accepts them.
The [transformer](../src/internal/migration/tokeycloak/transformer.go) leaves realm
roles and client-scope definitions empty, always enables standard flow, and lacks
mapping for service-account issuance, resource audiences, tenant/role claims,
per-client lifetime, MFA policy and secret references. Its user mapping omits the
canonical ID, tenant and roles; retaining the same `sub` is not established.
LLDAP uses a DN as the canonical user ID, so directory relocation itself requires
an explicit identity continuity strategy. Passwords and MFA credentials are not
migrated; absence of MFA data is not proof that no re-enrollment is needed.
**Close when:** the CLI accepts the required complete snapshot/registrations,
transforms preserve or explicitly reject every relevant policy/identity field,
and migration proof demonstrates subject continuity, claims, MFA and client
behavior. Until then, call these artifact generators rather than full migration.
### G04 — The replacement test harness does not prove a live provider swap
**Priority: high. Kind: verification and tooling gap.**
[Scenario B](../scripts/test-scenario-b.sh) and
[Scenario C](../scripts/test-scenario-c.sh) reference absent
`docker-compose.scenario-b.yml` / `docker-compose.scenario-c.yml`. They expect
`src/bin/`, while [src/Makefile](../src/Makefile) builds into root `bin/`, and invoke
a workstation-specific Go path from outside the Go module. Scenario C passes
`--base-dn` to a generator whose flag is `--basedn`.
Both scripts set `KEYCAPE_TEST_ISSUER`, but the
[profile suite](../src/tests/profile/profile_test.go) constructs its own
`httptest` server and does not consume that variable. The
[migration suites](../src/tests/migration/) validate generated structures with
fixtures. Thus even repairing the shell prerequisites would not make those
profile tests exercise the external Keycloak issuer.
**Close when:** reproducible stacks and an externally targeted conformance suite
exercise actual replacement providers, directory migration, claims and MFA;
record unchanged relying-party behavior and explicit migration limitations.
### G05 — Directory export can omit data without reporting it
**Priority: medium. Kind: implementation gap.**
The [exporter](../src/internal/migration/lldapexport/exporter.go) discovers groups
through each user's memberships. Empty/unreferenced groups are not enumerated.
Group lookup errors are skipped even though a comment says they are recorded in
the incompatibility report. The emitted success event and report therefore do
not establish a complete export. Iterating the group map also leaves group order
unspecified.
**Close when:** enumerate all groups independently, report or fail on incomplete
reads, define ordering, and test empty groups and backend failures. Preserve
completeness evidence before claiming deterministic full snapshots.
### G06 — The validator is narrower than schema enforcement
**Priority: medium. Kind: implementation/claim gap.**
[validator.go](../src/internal/validator/validator.go) implements useful structural
and semantic checks. However, `checkNoUnknownAttributes` is a placeholder that
rejects blank keys rather than enforcing an attribute allow-list; group
membership validation checks nonempty member IDs rather than complete referenced
identity existence. It does not derive its checks from the YAML schema.
**Close when:** implement the intended allow-list/reference constraints or narrow
the normative contract to the actual checks; add invalid-snapshot cases that
prove each stated rule. SCOPE now calls this limited snapshot validation.
### G07 — Optional tenant-role support is not wired into the server
**Priority: medium. Kind: integration gap.**
The [tenant-engine client](../src/internal/adapters/tenantengine/adapter.go) and
`TokenHandler.TenantEngine` are implemented and tested, including omission on
failure. [main.go](../src/cmd/keycape/main.go) supplies no such client and exposes
no configuration for it. The stock server therefore leaves it nil and omits
`tenant_roles`.
**Close when:** wire an explicit opt-in configuration and verify the built
executable, or document this as library-only support. It is an optional cache
claim, so absence is not itself a resource authorization failure.
### G08 — Runtime lifecycle and readiness are intentionally minimal
**Priority: medium. Kind: operational maturity gap.**
[Authorization state](../src/internal/server/oidc/authorize.go),
[code sessions](../src/internal/server/oidc/session.go),
[login sessions](../src/internal/server/oidc/login_session.go) and
[handoffs](../src/internal/server/oidc/handoff.go) reside in memory. Restart loses
in-flight and login state; multi-replica behavior is not supported by a shared
store. `/healthz` in [main.go](../src/cmd/keycape/main.go) returns a constant process
response without testing dependencies. The server uses `ListenAndServe`; TLS
termination is external. The signing key and registrations load
at startup; a fixed `key-1` identifier is used by token issuance.
[Logout](../src/internal/server/oidc/logout.go) clears the local login session;
it is not upstream logout or JWT revocation. No general refresh/introspection/
revocation or automatic rotation service is exposed. These need explicit
operational limits rather than an unqualified “high stability” label.
**Close when:** document/test the supported deployment topology, readiness and
restart behavior, and coordinate key/client lifecycle and consumer refresh.
Shared storage or refresh tokens need not be added if the accepted profile
explicitly excludes them. Benchmark before asserting resource-efficiency bounds.
### G09 — Packaging/bootstrap and older CLI credential handling need reconciliation
**Priority: medium. Kind: operational/tooling gap.**
[Development Compose](../docker-compose.dev.yml) refers to `config/dev-key.pem`
and `config/authelia`, neither supplied in the checkout. It is a scaffold requiring
bootstrap material. The [Dockerfile](../Dockerfile) packages only `keycape`, not
the migration/validator binaries. Image publication still points at the older
registry address in [.gitea/workflows/image.yaml](../.gitea/workflows/image.yaml);
that requires reconciliation with the Forgejo image location recorded by the
live workplan, not an assumption that every push deployed the current source.
The older [LLDAP exporter CLI](../src/cmd/lldap-export/main.go) accepts the bind
password on argv, and the migration scripts use that path. This falls short of
the newer caller CLI's private credential transport posture. Snapshot and realm
output are written with mode 0644, so operators must also consider identity-data
handling even though credential secrets are not part of those exports.
**Close when:** supply a reproducible bootstrap procedure, correct executable/
artifact locations and release references, and adopt safe credential input and
appropriate export permissions. A documented external bootstrap may satisfy
scope without storing secrets in this repository.
### G10 — Source capability is ahead of live custody and consumer adoption
**Priority: high for rollout; medium for handoff hygiene. Kind: external dependency/proof gap.**
[KEY-WP-0013](../workplans/KEY-WP-0013-approval-engine-resource-audience.md) records
approval clients awaiting custody admission, exact human callback and live proof.
Its earlier deployment observation identifies `main-153258b`, not the assessed
source revision. The [provisioning packet](../docs/approval-engine-provisioning-request.yaml)
is proposed metadata, not executable authorization or a live registration.
[KEY-WP-0014](../workplans/KEY-WP-0014-native-credential-lane-handoff.md) records
native JWT commands as implemented, but coordinated Qonto rotation and consumer
handoff remain open. The existing ops-warden login route obtains an **OpenBao
token**, so replacing it with issuer-JWT output would change the consumer
contract. [KEY-WP-0009](../workplans/KEY-WP-0009-provider-capabilities-and-service-identities.md)
was reopened because claimed handoff delivery lacks matching current receipts.
**Close when:** named custody/platform owners admit and provision exact lanes,
register the real callback, deploy and verify the new contracts, reconcile token
types at consumer boundaries, and retain handoff receipts. Repo-local source
changes cannot alone establish these outcomes.
## Deliberate exclusions are not defects
INTENT excludes general-purpose IAM, weakened flows and expanded-mode operations.
Dynamic registration, implicit/password grants, wildcard redirects and arbitrary
brokering should stay excluded unless the accepted profile changes. Resource
policy decisions and secret custody likewise remain with their owners.
The meaningful gaps are incomplete delivery or proof of the repo's claimed
subset, plus unqualified maturity claims. Full Keycloak feature parity, building
an authorization engine, or taking over OpenBao is not the proposed remedy.
## Recommended order
1. Resolve G01 protocol bindings and G02 canonical contract drift before claiming
complete profile conformance or widening rollout.
2. Treat G03G06 as a migration workstream: completeness and semantic preservation
first, then actual provider-replacement proof.
3. Decide G07 opt-in wiring and document/test the G08 supported topology.
4. Reconcile G09 bootstrap/release paths and complete G10 owner admissions and
live proof. Do not confuse passing local tests with those handoffs.
The findings above are an assessment backlog, not completed fixes or newly
approved production changes. Existing workplan references are retained where
applicable; new engineering work needs scoped implementation plans. This task
changes documentation only.

View file

@ -0,0 +1,27 @@
---
id: KEY-WP-0015
type: workplan
title: "Reconcile repository scope with implementation and intent"
domain: infotech
repo: key-cape
status: finished
owner: codex
topic_slug: scope-intent-assessment
created: "2026-09-05"
updated: "2026-09-05"
---
## Inventory implementation and document scope gaps
```task
id: KEY-WP-0015-T01
status: done
priority: medium
```
Reviewed source revision b989de4, INTENT, SCOPE, runtime composition, authentication
commands, adapters, migration/validator code, tests, packaging and open workplans.
Updated SCOPE.md to describe implemented surfaces and their actual limits.
Recorded evidence, ten prioritized gaps and closure criteria in
history/2026-09-05-011726-scope-intent-assessment.md. INTENT and implementation are
unchanged. Findings are assessment results, not implementation completion claims.