instar 1.3.215 → 1.3.217
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/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +7 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/types.d.ts +12 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/ApprenticeshipCycleSlaMonitor.d.ts +43 -0
- package/dist/monitoring/ApprenticeshipCycleSlaMonitor.d.ts.map +1 -0
- package/dist/monitoring/ApprenticeshipCycleSlaMonitor.js +78 -0
- package/dist/monitoring/ApprenticeshipCycleSlaMonitor.js.map +1 -0
- package/dist/monitoring/ApprenticeshipCycleStore.d.ts +52 -0
- package/dist/monitoring/ApprenticeshipCycleStore.d.ts.map +1 -0
- package/dist/monitoring/ApprenticeshipCycleStore.js +190 -0
- package/dist/monitoring/ApprenticeshipCycleStore.js.map +1 -0
- package/dist/monitoring/TokenLedgerPoller.d.ts +3 -0
- package/dist/monitoring/TokenLedgerPoller.d.ts.map +1 -1
- package/dist/monitoring/TokenLedgerPoller.js +7 -0
- package/dist/monitoring/TokenLedgerPoller.js.map +1 -1
- package/dist/server/AgentServer.d.ts +2 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +55 -0
- package/dist/server/AgentServer.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 +65 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +47 -47
- package/upgrades/1.3.216.md +44 -0
- package/upgrades/1.3.217.md +41 -0
- package/upgrades/apprenticeship-cycle-sla.eli16.md +37 -0
- package/upgrades/apprenticeship-cycle-store.eli16.md +62 -0
- package/upgrades/side-effects/apprenticeship-cycle-sla.md +17 -0
- package/upgrades/side-effects/apprenticeship-cycle-store.md +109 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Side-Effects Review — Apprenticeship Cycle Store
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `apprenticeship-cycle-store`
|
|
4
|
+
**Date:** `2026-06-03`
|
|
5
|
+
**Author:** `instar-codey`
|
|
6
|
+
**Second-pass reviewer:** `not required`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Adds `ApprenticeshipCycleStore`, a small better-sqlite3 store for one row per
|
|
11
|
+
apprenticeship differential cycle, plus authenticated HTTP routes for recording,
|
|
12
|
+
listing, fetching, and closing cycles. The server creates
|
|
13
|
+
`server-data/apprenticeship-cycles.db` when a state directory is available and
|
|
14
|
+
registers the SQLite handle with `SqliteRegistry`.
|
|
15
|
+
|
|
16
|
+
## Decision-point inventory
|
|
17
|
+
|
|
18
|
+
- `ApprenticeshipCycleStore.record` — add — validates required fields, stores
|
|
19
|
+
array fields as JSON, and defaults status to `open`.
|
|
20
|
+
- `ApprenticeshipCycleStore.list` — add — lists recent cycles globally or by
|
|
21
|
+
`instanceId`, with a bounded positive limit.
|
|
22
|
+
- `ApprenticeshipCycleStore.get` — add — returns one parsed cycle or null.
|
|
23
|
+
- `ApprenticeshipCycleStore.closeCycle` — add — marks a cycle closed and returns
|
|
24
|
+
the updated parsed row.
|
|
25
|
+
- `/apprenticeship/cycles*` routes — add — bearer-protected CRUD-style API with
|
|
26
|
+
503 when the store is unavailable, 400 for invalid input, and 404 for unknown
|
|
27
|
+
ids.
|
|
28
|
+
|
|
29
|
+
## 1. Over-block
|
|
30
|
+
|
|
31
|
+
The store rejects missing `instanceId`, non-positive `cycleNumber`, empty `task`,
|
|
32
|
+
empty `menteeOutput`, and non-string entries in array fields. That is intentional:
|
|
33
|
+
these are structural capture records, and accepting malformed rows would make the
|
|
34
|
+
later retro-harvest less reliable.
|
|
35
|
+
|
|
36
|
+
The route layer returns 503 when the store is not wired. This is stricter than
|
|
37
|
+
returning an empty list, but it is the right failure mode because callers need to
|
|
38
|
+
know the feature is unavailable rather than "no cycles exist."
|
|
39
|
+
|
|
40
|
+
## 2. Under-block
|
|
41
|
+
|
|
42
|
+
The store does not enforce that `instanceId` references an existing
|
|
43
|
+
apprenticeship instance. That keeps this Tier-1 change additive and avoids
|
|
44
|
+
coupling the cycle recorder to instance lifecycle transitions. A later workflow
|
|
45
|
+
layer can add instance-aware capture if it needs that guarantee.
|
|
46
|
+
|
|
47
|
+
The `coaching` and `kind` fields are plain strings, not constrained enums. The
|
|
48
|
+
current default `kind` is `differential-cycle`; preserving strings keeps room for
|
|
49
|
+
future cycle subtypes without a migration.
|
|
50
|
+
|
|
51
|
+
## 3. Level-of-abstraction fit
|
|
52
|
+
|
|
53
|
+
Persistence belongs in `src/monitoring` with the other small operational stores,
|
|
54
|
+
not in the apprenticeship lifecycle JSON registry. The lifecycle registry owns
|
|
55
|
+
instance state and gates; the cycle store owns repeatable evidence captured
|
|
56
|
+
during an active mentorship.
|
|
57
|
+
|
|
58
|
+
The HTTP routes stay thin: they validate availability, call the store, and map
|
|
59
|
+
store validation errors to 400 responses.
|
|
60
|
+
|
|
61
|
+
## 4. Signal vs authority compliance
|
|
62
|
+
|
|
63
|
+
No conversational/product judgment is delegated to brittle logic. The change only
|
|
64
|
+
persists explicit caller-provided fields and exposes them through authenticated
|
|
65
|
+
routes. It does not decide whether a cycle was good, whether a mentor was right,
|
|
66
|
+
or whether an instance may complete.
|
|
67
|
+
|
|
68
|
+
## 5. Interactions
|
|
69
|
+
|
|
70
|
+
- **SqliteRegistry:** the store registers and unregisters its handle so native
|
|
71
|
+
SQLite lifecycle checks include the new database.
|
|
72
|
+
- **AgentServer shutdown:** the store closes during server stop, best-effort,
|
|
73
|
+
beside the other monitoring stores.
|
|
74
|
+
- **ApprenticeshipProgram:** instance routes remain unchanged. Cycle capture is
|
|
75
|
+
adjacent to, not inside, the lifecycle transition gate.
|
|
76
|
+
- **Monitoring/e2e:** the e2e alive path asserts `POST /apprenticeship/cycles`
|
|
77
|
+
returns 201 when the server has the store and not 503.
|
|
78
|
+
|
|
79
|
+
## 6. External surfaces
|
|
80
|
+
|
|
81
|
+
Adds four bearer-authenticated API routes:
|
|
82
|
+
|
|
83
|
+
- `POST /apprenticeship/cycles`
|
|
84
|
+
- `GET /apprenticeship/cycles?instanceId=&limit=`
|
|
85
|
+
- `GET /apprenticeship/cycles/:id`
|
|
86
|
+
- `POST /apprenticeship/cycles/:id/close`
|
|
87
|
+
|
|
88
|
+
Adds one database file under server state when the server is running:
|
|
89
|
+
`server-data/apprenticeship-cycles.db`.
|
|
90
|
+
|
|
91
|
+
## 7. Rollback cost
|
|
92
|
+
|
|
93
|
+
Rollback is a code and route revert. Existing `apprenticeship-cycles.db` files
|
|
94
|
+
can remain inert on disk; the server simply stops opening them after rollback.
|
|
95
|
+
No migration is required because no existing schema is modified.
|
|
96
|
+
|
|
97
|
+
## Conclusion
|
|
98
|
+
|
|
99
|
+
Ship. This is an additive Tier-1 persistence/API surface with focused store,
|
|
100
|
+
integration, and e2e coverage. The only failure-mode hardening is returning 503
|
|
101
|
+
when the store is unavailable, which is the correct liveness signal.
|
|
102
|
+
|
|
103
|
+
## Evidence pointers
|
|
104
|
+
|
|
105
|
+
- `tests/unit/apprenticeship-cycle-store.test.ts`
|
|
106
|
+
- `tests/unit/SqliteRegistry-wiring.test.ts`
|
|
107
|
+
- `tests/integration/apprenticeship-routes.test.ts`
|
|
108
|
+
- `tests/e2e/apprenticeship-lifecycle.test.ts`
|
|
109
|
+
|