instar 1.3.198 → 1.3.200
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/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/AutonomousSessions.d.ts +2 -0
- package/dist/core/AutonomousSessions.d.ts.map +1 -1
- package/dist/core/AutonomousSessions.js +2 -0
- package/dist/core/AutonomousSessions.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +35 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionClock.d.ts +57 -0
- package/dist/core/SessionClock.d.ts.map +1 -0
- package/dist/core/SessionClock.js +128 -0
- package/dist/core/SessionClock.js.map +1 -0
- package/dist/core/SessionClockReader.d.ts +18 -0
- package/dist/core/SessionClockReader.d.ts.map +1 -0
- package/dist/core/SessionClockReader.js +35 -0
- package/dist/core/SessionClockReader.js.map +1 -0
- 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 +12 -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 +118 -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 +12 -0
- package/upgrades/1.3.199.md +24 -0
- package/upgrades/1.3.200.md +25 -0
- package/upgrades/side-effects/APPRENTICESHIP-STEP1-PROGRAM-SCAFFOLD-SPEC.md +82 -0
- package/upgrades/side-effects/session-clock-step1.md +52 -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,52 @@
|
|
|
1
|
+
# Side-Effects Review — Session Clock Step 1 (SessionClock + GET /session/clock)
|
|
2
|
+
|
|
3
|
+
**Slug:** `session-clock-step1`
|
|
4
|
+
**Date:** `2026-06-02`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Tier:** 2 (driven by the converged + approved spec `ROBUST-SESSION-TIME-AWARENESS-SPEC.md`)
|
|
7
|
+
**Spec:** `docs/specs/ROBUST-SESSION-TIME-AWARENESS-SPEC.md` (review-convergence iteration 3, approved)
|
|
8
|
+
|
|
9
|
+
## Summary of the change
|
|
10
|
+
|
|
11
|
+
Step 1 of the time-awareness fix: the compute + query surface.
|
|
12
|
+
- `src/core/SessionClock.ts` — pure tier0 module: `computeSessionClock(input, nowMs)` (elapsed/remaining with clock-skew clamping + the status matrix), `deriveLabel(goal)` (the sanitized, cap-80, control-char/angle-bracket-stripped label that is the ONLY task text ever injected/served), `humanizeDuration`.
|
|
13
|
+
- `src/core/SessionClockReader.ts` — read-only I/O layer: maps ACTIVE autonomous-state records → computed clocks, with optional topic binding. Reuses `AutonomousSessions.activeAutonomousJobs()`.
|
|
14
|
+
- `src/core/AutonomousSessions.ts` — `AutonomousJobSummary` gains `durationSeconds` (parsed from the existing `duration_seconds` front-matter field). Additive.
|
|
15
|
+
- `src/server/routes.ts` — new read-only `GET /session/clock` (optional `?topic=N`). Bearer-gated (inherits app-wide auth). Leak-bounded: returns the computed clock + sanitized `label` only, never the raw `goal`.
|
|
16
|
+
- `src/scaffold/templates.ts` + `src/core/PostUpdateMigrator.ts` — CLAUDE.md "Session Clock" awareness (template for new agents; content-sniffed `migrateClaudeMd` block for existing agents).
|
|
17
|
+
|
|
18
|
+
## Decision-point inventory
|
|
19
|
+
- route exposure: read vs write → read-only (GET only; POST → 404). No gate, no mutation.
|
|
20
|
+
- label: inject raw goal vs derived → derived + sanitized + capped. The raw goal never leaves the record.
|
|
21
|
+
- record field: `end_at` vs `started_at`+`duration_seconds` → the latter (canonical, matches the stop-hook + setup-autonomous.sh schema); `endsAt` is derived.
|
|
22
|
+
|
|
23
|
+
## 1. Over-correction risk
|
|
24
|
+
None — purely additive observability. No existing behavior changes. A healthy agent with no time-boxed record gets `{ sessions: [] }`.
|
|
25
|
+
|
|
26
|
+
## 2. Under-correction risk
|
|
27
|
+
Step 1 is the QUERY surface only; the per-turn INJECTION (the higher-impact fix for the incident) is Step 2 (emit-session-clock.sh + hooks), a separate PR. Documented in the spec sequencing.
|
|
28
|
+
|
|
29
|
+
## 3. Level-of-abstraction fit
|
|
30
|
+
Compute is pure (SessionClock.ts, no I/O, fully unit-tested both sides of every boundary); I/O is isolated (SessionClockReader.ts); the route is a thin reader. The record-enumeration reuses the existing AutonomousSessions module rather than duplicating frontmatter parsing.
|
|
31
|
+
|
|
32
|
+
## 4. Signal vs Authority
|
|
33
|
+
Tier0, deterministic, no LLM, no gate. Pure computation + a read route. Appropriate.
|
|
34
|
+
|
|
35
|
+
## 5. External surfaces
|
|
36
|
+
One new read-only HTTP route (`GET /session/clock`), Bearer-gated like `/tokens/summary`. **Leak-bound:** the response carries the sanitized `label` only — never the raw `goal`/task text (verified by integration + E2E assertions). No config/schema change.
|
|
37
|
+
|
|
38
|
+
## 6. Interactions with existing primitives
|
|
39
|
+
`AutonomousJobSummary.durationSeconds` is additive (existing consumers unaffected — AutonomousSessions unit tests still green). The route composes with the existing auth middleware. No change to the autonomous-state writer or the stop-hook.
|
|
40
|
+
|
|
41
|
+
## 7. Rollback cost
|
|
42
|
+
Trivial: remove the route + the two new modules + the additive `durationSeconds` field + the CLAUDE.md block. No persistent state, no migration of data.
|
|
43
|
+
|
|
44
|
+
## Migration parity
|
|
45
|
+
- New agents: the route ships in code; the CLAUDE.md template carries the awareness.
|
|
46
|
+
- Existing agents: the route reaches them on the normal dist update (code); `migrateClaudeMd` content-sniffs `/session/clock` and appends the awareness block (idempotent).
|
|
47
|
+
|
|
48
|
+
## Tests (all three tiers)
|
|
49
|
+
- Unit: `SessionClock` (14 — full status matrix, clock-skew clamp, label derivation/sanitization incl. `<promise>`-token stripping + cap-80) + `SessionClockReader` (6 — record parsing, topic binding, goal→label end-to-end, missing dir).
|
|
50
|
+
- Integration: `session-clock-route` (4 — 200 with computed fields, `{sessions:[]}` when none, topic filter, leak-bound: raw goal never in the response).
|
|
51
|
+
- E2E: `session-clock-lifecycle` (4 — real AgentServer boot, route alive 200 not 503, leak-bound, Bearer required, read-only POST→404).
|
|
52
|
+
- No regressions: AutonomousSessions (13) + migrateClaudeMd (3) still green; `tsc --noEmit` clean.
|