instar 1.3.197 → 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.
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +16 -1
- package/dist/commands/setup.js.map +1 -1
- package/dist/core/ApprenticeshipProgram.d.ts +211 -0
- package/dist/core/ApprenticeshipProgram.d.ts.map +1 -0
- package/dist/core/ApprenticeshipProgram.js +433 -0
- package/dist/core/ApprenticeshipProgram.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +25 -2
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/retroHarvestValidator.d.ts +79 -0
- package/dist/core/retroHarvestValidator.d.ts.map +1 -0
- package/dist/core/retroHarvestValidator.js +256 -0
- package/dist/core/retroHarvestValidator.js.map +1 -0
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +7 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +1 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +48 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +16 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts +5 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +99 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/scripts/validate-retro-harvest.mjs +31 -237
- package/src/data/builtin-manifest.json +63 -63
- package/src/scaffold/templates.ts +7 -0
- package/upgrades/1.3.198.md +24 -0
- package/upgrades/1.3.199.md +24 -0
- package/upgrades/side-effects/APPRENTICESHIP-STEP1-PROGRAM-SCAFFOLD-SPEC.md +82 -0
- package/upgrades/side-effects/fix-bootwrapper-install-path.md +83 -0
|
@@ -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.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Side-Effects Review — Boot-wrapper reinstall: put node on PATH for native postinstalls
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `fix-bootwrapper-install-path`
|
|
4
|
+
**Date:** `2026-06-02`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Tier:** 1 (small, well-understood bugfix; ELI16 + side-effects, no converged spec) — but HIGH blast radius (boot shim), reviewed accordingly
|
|
7
|
+
**Parent principle:** Cross-Machine Coherence / Bootstrap Robustness — an agent must be able to self-heal its own install
|
|
8
|
+
|
|
9
|
+
## Summary of the change
|
|
10
|
+
|
|
11
|
+
The boot wrapper (`instar-boot.cjs` / `instar-boot.sh`, generated by `installBootWrapper`
|
|
12
|
+
in `src/commands/setup.ts`) self-heals a missing shadow install by running `npm install`.
|
|
13
|
+
That `npm install` was spawned with **no `env` / no PATH augmentation**, so native
|
|
14
|
+
postinstall scripts (e.g. `sharp`: `sh -c "node install/check.js || npm run build"`) ran in
|
|
15
|
+
a subshell whose PATH — under a launchd-spawned boot child — has no `node`/`npm`, dying with
|
|
16
|
+
`command not found`. The reinstall then aborts and the shadow install never heals.
|
|
17
|
+
|
|
18
|
+
**Observed live (2026-06-02):** a throwaway mini agent could not start — `instar-boot`
|
|
19
|
+
looped on "Shadow install missing", and a manual reinstall reproduced it: it failed on
|
|
20
|
+
`sharp`'s postinstall (`sh: node: command not found`). Re-running with `node` on PATH
|
|
21
|
+
succeeded immediately.
|
|
22
|
+
|
|
23
|
+
### What changed
|
|
24
|
+
- `src/commands/setup.ts` — `installBootWrapper`:
|
|
25
|
+
- **`.cjs` (jsWrapper):** the reinstall `execFileSync(nodeBin, [npmCli, 'install', …])` now
|
|
26
|
+
passes `env: installEnv` where `installEnv` prepends `path.dirname(nodeBin)` to `PATH` and
|
|
27
|
+
sets `npm_config_scripts_prepend_node_path: 'true'`.
|
|
28
|
+
- **`.sh` (bashWrapper):** the reinstall now runs with
|
|
29
|
+
`PATH="$(dirname "$NODE_BIN"):$PATH" npm_config_scripts_prepend_node_path=true` prefixed.
|
|
30
|
+
- `src/core/PostUpdateMigrator.ts` — `migrateBootWrapperAbiCheck`: the "already current" guard
|
|
31
|
+
now ALSO requires the `npm_config_scripts_prepend_node_path` marker, so existing agents whose
|
|
32
|
+
wrapper predates this fix are regenerated on update (Migration Parity).
|
|
33
|
+
|
|
34
|
+
## Decision-point inventory
|
|
35
|
+
- reinstall env: augment vs inherit → augment (prepend node dir + npm flag). Inheriting the
|
|
36
|
+
launchd PATH is the bug.
|
|
37
|
+
- migration: add a 3rd required marker vs leave 2 → add the marker (otherwise deployed agents
|
|
38
|
+
with the 2 prior markers never regenerate and never get the fix).
|
|
39
|
+
- auto-re-port / auto-anything else: none — purely the reinstall env.
|
|
40
|
+
|
|
41
|
+
## 1. Over-correction risk
|
|
42
|
+
The env only AUGMENTS PATH (prepends node dir; keeps the rest) and sets one npm flag. A healthy
|
|
43
|
+
agent never enters the reinstall branch at all (`if (!fs.existsSync(SHADOW))`), so the change is
|
|
44
|
+
inert unless the shadow install is actually missing. `npm_config_scripts_prepend_node_path` is
|
|
45
|
+
npm's own documented option for exactly this case.
|
|
46
|
+
|
|
47
|
+
## 2. Under-correction risk
|
|
48
|
+
The migration regenerates only wrappers missing the new marker; agents already regenerated stay
|
|
49
|
+
put (idempotent). The `.sh` variant is for manual/Linux use; the launchd-critical path is `.cjs`.
|
|
50
|
+
|
|
51
|
+
## 3. Level-of-abstraction fit
|
|
52
|
+
The fix lives in the single boot-wrapper generator (`installBootWrapper`) that both `init` and the
|
|
53
|
+
migration call — one source, both consumers. No scattering.
|
|
54
|
+
|
|
55
|
+
## 4. Signal vs Authority
|
|
56
|
+
Pure deterministic env construction (no LLM/heuristic). Appropriate.
|
|
57
|
+
|
|
58
|
+
## 5. External surfaces
|
|
59
|
+
None. No route/config-schema change. The generated wrapper gains an env on one spawn.
|
|
60
|
+
|
|
61
|
+
## 6. Interactions with existing primitives
|
|
62
|
+
The reinstall's debounce marker, the ABI-aware node self-heal, and the version-managed-node
|
|
63
|
+
candidate discovery are all unchanged; this only adds an env to the npm spawn and a 3rd marker
|
|
64
|
+
to the migration's idempotency sniff (composes with the existing two).
|
|
65
|
+
|
|
66
|
+
## 7. Rollback cost
|
|
67
|
+
Trivial: drop the `env`/PATH additions and the 3rd marker clause. No persistent state.
|
|
68
|
+
|
|
69
|
+
## Migration parity
|
|
70
|
+
- New agents: `installBootWrapper` (via `init`) writes the fixed wrapper.
|
|
71
|
+
- Existing agents: `migrateBootWrapperAbiCheck` regenerates `instar-boot.cjs` because the new
|
|
72
|
+
`npm_config_scripts_prepend_node_path` marker is absent. Idempotent — re-running skips once the
|
|
73
|
+
marker is present.
|
|
74
|
+
|
|
75
|
+
## Tests
|
|
76
|
+
`tsc --noEmit` clean. `PostUpdateMigrator-bootWrapperAbiCheck` extended to 8 tests (all green):
|
|
77
|
+
the "skip" idempotency case now requires all THREE markers; a new regen case for a wrapper with
|
|
78
|
+
the two prior markers but missing the install-path marker; a generated-content test asserting the
|
|
79
|
+
`.cjs` reinstall passes `env: installEnv` with `npm_config_scripts_prepend_node_path` + the PATH
|
|
80
|
+
prepend AND that the generated `.cjs` passes `node --check` (guards against template-escaping
|
|
81
|
+
bricking the boot shim); a `.sh` generated-content test. 30 sibling boot-wrapper tests
|
|
82
|
+
(`bootWrapperCjs`, `plist-coherence`, `lifeline-shadow-install-self-heal`, `init-join-launchd-handoff`)
|
|
83
|
+
all still green — no regressions.
|