instar 1.3.198 → 1.3.199

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,82 @@
1
+ # Side-Effects Review — Apprenticeship Step 1: Program Scaffold
2
+
3
+ **Version / slug:** `APPRENTICESHIP-STEP1-PROGRAM-SCAFFOLD-SPEC`
4
+ **Date:** `2026-06-01`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `not required` (converged: 5 internal reviewers + codex gpt-5.5, 3 rounds)
7
+
8
+ ## Summary of the change
9
+
10
+ Builds Step 1 of the Apprenticeship Program (Tier-3 umbrella #675). Adds the minimal program
11
+ scaffold: an instance-as-project registry + two lifecycle gates (the **retro-gate** = a new
12
+ instance can't transition `pending→active` until the prior instance's retro-harvest validates;
13
+ the **doc-gate** = an instance can't transition `active→complete` until its required artifacts are
14
+ verified present from live state) + the role model. Relocates the Step-0 validator's pure logic to
15
+ `src/core/retroHarvestValidator.ts` (so it's an in-process typed import — the `src`→`scripts/.mjs`
16
+ import the convergence caught couldn't compile).
17
+
18
+ ## Decision-point inventory
19
+
20
+ Two structural gates (`evaluateStartGate`, `evaluateCompletionGate`) + the status transition table.
21
+ Per Signal vs Authority / The Body and the Mind (spec §3.6), these are **structural preconditions on
22
+ OBJECTIVE artifacts** (does a validated harvest exist? is there an instance-scoped ledger entry?) —
23
+ NOT quality judgments. The *quality* call (did the mentor internalize the lessons / was the audit
24
+ real) stays with the overseer. Every gate verdict is appended to `logs/apprenticeship-decisions.jsonl`.
25
+
26
+ ## 1. Over-block
27
+
28
+ **What legitimate inputs does this reject?** A `pending→active` transition with no valid prior/bootstrap
29
+ harvest; an `active→complete` with a missing required artifact; an illegal status transition; a
30
+ duplicate or bad-charset instance id; a `partial-accepted` harvest with no acceptance metadata. All
31
+ are genuine preconditions. The gates are scoped to the program's own instance lifecycle — they never
32
+ block a global action.
33
+
34
+ ## 2. Under-block
35
+
36
+ **What does this still miss?** The retro-gate enforces *structural* validity only — it trusts the
37
+ harvest's recorded `fidelityReview` stamp (Step 0's independent review was the authority); a forged
38
+ stamp is not re-caught here (stated, §3.3). The doc-gate verifies artifact *presence* from live state,
39
+ not artifact *quality*. `requiredArtifacts` is the checklist definition; truth is always re-derived
40
+ from injected deps, never a stored boolean.
41
+
42
+ ## 3. Level-of-abstraction fit
43
+
44
+ **Right layer?** Yes. `ApprenticeshipProgram` is a `src/core` module over a file-based JSON store
45
+ (the `CommitmentTracker` atomic-write + CAS pattern), gates are pure + unit-tested, routes are a
46
+ nullable `RouteContext` field with the standard 503-guard, wired in `AgentServer`. The validator
47
+ relocation matches the `BackfillCore` precedent (pure logic in `src/`, the `.mjs` re-exports for CLI).
48
+
49
+ ## 4. Testing
50
+
51
+ - **Unit** (`tests/unit/apprenticeship-program.test.ts`, 29): both gates both sides; the status table
52
+ (legal/illegal/`complete`-terminal); charset clamp + dup-reject; path-confinement (a traversal
53
+ `harvestRef` is ignored, canonical path used); wiring-integrity (injected deps real, not no-ops);
54
+ `partial-accepted` with/without acceptance. Plus the validator's 33 cases (repointed to the TS source).
55
+ - **Integration** (`tests/integration/apprenticeship-routes.test.ts`, 10): the routes incl.
56
+ auth-negative (no/wrong token → 401/403), create→transition gating, the decision-audit line.
57
+ - **E2E** (`tests/e2e/apprenticeship-lifecycle.test.ts`, 3): Phase-1 "feature is alive" —
58
+ `/apprenticeship/instances` returns 200 through the production `AgentServer` init path.
59
+ - Verified independently: `tsc --noEmit` clean; 62 unit + 15 integration + 3 e2e green; `pnpm build` ok.
60
+
61
+ ## 5. Migration Parity + Agent-Awareness
62
+
63
+ - **Agent-Awareness:** added to **both** `generateClaudeMd()` (new agents) AND a `migrateClaudeMd()`
64
+ content-sniff entry in `PostUpdateMigrator` (existing agents) — idempotent, shares the
65
+ `**Apprenticeship Program**` marker so freshly-init agents aren't double-patched.
66
+ - **Migration Parity:** `.instar/apprenticeship/instances.json` is runtime state (no migration). No
67
+ config flag (the scaffold is additive + passive + actively needed this run — decided, not conditional).
68
+ - **Bootstrap harvest:** `acceptedBy: justin` + `acceptedAt` added to `echo-to-codey-mentorship.md`
69
+ (Justin approved Step 0 which contained it) so the retro-gate's `partial-accepted` rule passes; still
70
+ validates.
71
+ - **Publish:** touches `src/core` + `src/server` + `src/scaffold` → a `NEXT.md` publish fragment is
72
+ added (`upgrades/next/apprenticeship-step1-program-scaffold.md`, minor bump).
73
+
74
+ ## 6. Rollback
75
+ Revert the commit; `.instar/apprenticeship/instances.json` is runtime state with no migration to undo;
76
+ the validator relocation is behavior-preserving (Step-0 tests pass against the relocated logic).
77
+
78
+ ## 7. Follow-up (CI fix)
79
+ The `capabilities-discoverability` lint requires every new route prefix to be classified. The
80
+ `/apprenticeship` prefix is **agent-facing**, so it is added to `CAPABILITY_INDEX` in
81
+ `src/server/CapabilityIndex.ts` (surfaces in `/capabilities`) rather than `INTERNAL_PREFIXES`. No
82
+ new behavior — classification metadata + the endpoint list for discovery.