@a-company/paradigm 6.6.6 → 7.0.0
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/{accept-orchestration-JHDCVHB2.js → accept-orchestration-YO2V2WYA.js} +1 -1
- package/dist/{agents-suggest-IKY6VD2R.js → agents-suggest-WZEGQT5E.js} +1 -1
- package/dist/ambient-7HBJHJL2.js +2 -0
- package/dist/{ambient-FNNFB4AP.js → ambient-OX7YJ4PJ.js} +1 -1
- package/dist/ambient-SST5CLEC.js +35 -0
- package/dist/captain-YUP3KVCA.js +2 -0
- package/dist/chunk-33ERV2MW.js +18 -0
- package/dist/chunk-3MZ4J2LF.js +2 -0
- package/dist/chunk-47YPID6H.js +142 -0
- package/dist/chunk-6AKNXD22.js +32 -0
- package/dist/chunk-6HVOZANP.js +4 -0
- package/dist/chunk-ACJWUOMA.js +3 -0
- package/dist/chunk-B5KLSBOZ.js +2 -0
- package/dist/chunk-DLMDHS2X.js +10 -0
- package/dist/chunk-FRQRREJ6.js +29 -0
- package/dist/{chunk-5RFISGUW.js → chunk-G6DK3ND3.js} +250 -25
- package/dist/{chunk-XKNJSPB5.js → chunk-JCGCPAHF.js} +1 -1
- package/dist/chunk-K54L6CFR.js +25 -0
- package/dist/chunk-QBIQ2FYB.js +20 -0
- package/dist/chunk-QEQCPVF5.js +4 -0
- package/dist/chunk-ROU3F2HZ.js +6 -0
- package/dist/chunk-S4J337EQ.js +504 -0
- package/dist/chunk-V6MIKLMY.js +18 -0
- package/dist/chunk-WROJSWAO.js +93 -0
- package/dist/{chunk-TQOT2LBO.js → chunk-YXLGVOZO.js} +1 -1
- package/dist/chunk-ZSWXLFN7.js +12 -0
- package/dist/{compliance-J3VOV445.js → compliance-MLG4W6S4.js} +1 -1
- package/dist/{diff-ANKTFDRA.js → diff-MC6AXLKX.js} +1 -1
- package/dist/{docs-TSAAS4W3.js → docs-3YFNNZRV.js} +1 -1
- package/dist/doctor-CBZYYQQH.js +2 -0
- package/dist/{hooks-45WDP6QS.js → hooks-AXBWYJ5V.js} +1 -1
- package/dist/index.js +4 -4
- package/dist/mcp.js +3 -3
- package/dist/{migrate-R64OQGSM.js → migrate-5M4KUQ2L.js} +1 -1
- package/dist/{nomination-engine-NCLTGMAK.js → nomination-engine-AQHU2KBU.js} +1 -1
- package/dist/notebook-loader-6DYFMNJ2.js +2 -0
- package/dist/orchestrate-GMYEBA5T.js +8 -0
- package/dist/orchestration-G5MAY6IA.js +2 -0
- package/dist/propose-block-ZEMEWJQF.js +2 -0
- package/dist/{providers-TBPOE4DI.js → providers-5EHD45C6.js} +1 -1
- package/dist/reindex-XTRF23F7.js +2 -0
- package/dist/{serve-3FMUWW5K.js → serve-SMGWGJLM.js} +1 -1
- package/dist/session-tracker-BZ7FU4AT.js +2 -0
- package/dist/session-work-log-QXPAXY5K.js +2 -0
- package/dist/session-work-log-T2IE4Y4T.js +2 -0
- package/dist/{shift-TNA2E5O7.js → shift-JBCEDCGA.js} +2 -2
- package/dist/solo-OWR3MX74.js +3 -0
- package/dist/{spawn-KKDDR6UR.js → spawn-PHA2SVQ3.js} +1 -1
- package/dist/task-loader-IGQQ6ZFL.js +2 -0
- package/dist/task-settlement-NW4XMJGJ.js +3 -0
- package/dist/{team-PEGP6F7S.js → team-J2YXPEGX.js} +1 -1
- package/dist/team-funnel-RAJ6EDG3.js +2 -0
- package/dist/tools-HNJ7D5IO.js +2 -0
- package/dist/university-content/notes/N-para-801-cid-becomes-real.md +60 -0
- package/dist/university-content/notes/N-para-801-falsifiable-self-improvement.md +66 -0
- package/dist/university-content/notes/N-para-801-honest-routing-and-the-method.md +57 -0
- package/dist/university-content/notes/N-para-801-orchestration-emits-dag.md +60 -0
- package/dist/university-content/notes/N-para-801-settlement-closes-the-loop.md +64 -0
- package/dist/university-content/notes/N-para-801-the-task-dag.md +93 -0
- package/dist/university-content/paths/LP-para-801.yaml +43 -0
- package/dist/university-content/quizzes/Q-para-801-cid-becomes-real.yaml +54 -0
- package/dist/university-content/quizzes/Q-para-801-falsifiable-self-improvement.yaml +54 -0
- package/dist/university-content/quizzes/Q-para-801-honest-routing-and-the-method.yaml +54 -0
- package/dist/university-content/quizzes/Q-para-801-orchestration-emits-dag.yaml +54 -0
- package/dist/university-content/quizzes/Q-para-801-settlement-closes-the-loop.yaml +54 -0
- package/dist/university-content/quizzes/Q-para-801-the-task-dag.yaml +54 -0
- package/dist/university-ui/assets/{index-DrtbBC21.js → index-B8hm_MdR.js} +2 -2
- package/dist/university-ui/assets/{index-DrtbBC21.js.map → index-B8hm_MdR.js.map} +1 -1
- package/dist/university-ui/index.html +1 -1
- package/package.json +1 -1
- package/dist/ambient-AI42BOM5.js +0 -35
- package/dist/chunk-3OXR6F65.js +0 -666
- package/dist/chunk-4N56FRNE.js +0 -29
- package/dist/chunk-6QXBXZF6.js +0 -3
- package/dist/chunk-AMLD7IYC.js +0 -10
- package/dist/chunk-DVZWCXB6.js +0 -2
- package/dist/chunk-F6E3HW45.js +0 -14
- package/dist/chunk-K7X3Z3GL.js +0 -4
- package/dist/chunk-LAYBUKMB.js +0 -14
- package/dist/chunk-MU5YWTNE.js +0 -24
- package/dist/chunk-PMKZMCTS.js +0 -111
- package/dist/chunk-XQLO5URP.js +0 -11
- package/dist/doctor-L5XZENCF.js +0 -2
- package/dist/notebook-loader-3J2OFMS3.js +0 -2
- package/dist/orchestrate-UG5QXNAU.js +0 -8
- package/dist/reindex-PTIQ2UGY.js +0 -2
- package/dist/session-tracker-HHNY6J4I.js +0 -2
- package/dist/session-work-log-MEJ33TYD.js +0 -2
- package/dist/session-work-log-ZVVJGO7X.js +0 -2
- package/dist/task-loader-NZFDTUQ5.js +0 -2
- package/dist/tools-PUSDXUYE.js +0 -2
- /package/dist/{chunk-HXGYVS2N.js → chunk-ECLUYHAR.js} +0 -0
- /package/dist/{platform-server-ANOALDPL.js → platform-server-WIBVYHIV.js} +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: N-para-801-honest-routing-and-the-method
|
|
3
|
+
title: 'Lesson 6: Honest Routing & the Dogfood Method'
|
|
4
|
+
type: note
|
|
5
|
+
author: paradigm
|
|
6
|
+
created: '2026-06-13'
|
|
7
|
+
updated: '2026-06-13'
|
|
8
|
+
tags:
|
|
9
|
+
- course
|
|
10
|
+
- para-801
|
|
11
|
+
- close-the-loop
|
|
12
|
+
- classification
|
|
13
|
+
- adversarial-review
|
|
14
|
+
symbols: []
|
|
15
|
+
difficulty: intermediate
|
|
16
|
+
estimatedMinutes: 7
|
|
17
|
+
prerequisites: []
|
|
18
|
+
category: paradigm-core
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## The Front Door: Honest Classification
|
|
22
|
+
|
|
23
|
+
The Spine closes the *back* of the loop (work → learning). The "Front Door" fixes the *front*: getting any user's request to the right team without an expert driving the orchestrator by hand.
|
|
24
|
+
|
|
25
|
+
The keyword classifier was rebuilt in v7 as **confidence-scored with intent-verb anchoring**. Three concrete fixes:
|
|
26
|
+
|
|
27
|
+
- **The "bugfix poison-pill" is gone.** An audit of a *broken* system used to route to `[security, builder]` — i.e. the word "broken" silently summoned a fixer. New `audit` / `design` / `research` families map to **read-only analyst rosters that never route to a fixer.** Asking for an analysis no longer triggers an implementation.
|
|
28
|
+
- **Misroutes are now visible.** Every mode response surfaces `{ type, confidence, alternativeType, overrideHint }`. A wrong classification is no longer silent — the user sees the second-best guess and how to override it.
|
|
29
|
+
- **One authoritative classifier.** A second, divergent inline classifier is collapsed; `classification.type` is the single source of truth.
|
|
30
|
+
|
|
31
|
+
## Full-Roster Routability
|
|
32
|
+
|
|
33
|
+
The second front-door fix: the trigger-based `agent-matcher` becomes the primary roster/suggestion source, so specialists that were previously **unroutable by auto-orchestration** — `product` (North), `forge` (Loid), `researcher` (Scout), `dx` (Helix) — can now actually be assembled automatically, not only by a human naming them. The best agents being un-summonable was itself an audit finding: a team you cannot reach is a team you do not have.
|
|
34
|
+
|
|
35
|
+
## The Method: Dogfooding the Cross-Check
|
|
36
|
+
|
|
37
|
+
The most teachable thing about v7 is not any single feature — it is **how v7 was built.** Every claim above was caught, corrected, or confirmed *before it shipped* by Paradigm cross-checking itself. This is a Paradigm practice you should copy.
|
|
38
|
+
|
|
39
|
+
### Step 1 — The self-audit (file-and-line evidence)
|
|
40
|
+
|
|
41
|
+
v7 began with a two-slice self-audit: the task system, then the orchestration engine that runs every other audit. The discipline was **file-and-line evidence, not vibes.** "The learning loop is broken" is a vibe; "`task_done` at `task-loader.ts` feeds nothing — here is the dead joint" is a finding. Every claim was anchored to code you could open.
|
|
42
|
+
|
|
43
|
+
### Step 2 — The adversarial review
|
|
44
|
+
|
|
45
|
+
A designed spec is a *hypothesis*, not a fact. Before the learning wiring was built, an adversarial pass (the reviewer's job: try to *break* the design against the real code) caught **three keystone claims that were false or circular**:
|
|
46
|
+
|
|
47
|
+
1. The belief-delta gate ran on **hardcoded** confidence numbers — promoting on the difference of two constants (Lesson 3 covers the honest fix).
|
|
48
|
+
2. "Both worlds flow through `completeTask`" was **false** — the CLI orchestrator emits no tasks (scope was honestly narrowed to the MCP path).
|
|
49
|
+
3. The JPS metric was **circular** — clean work and a dead chain both read zero (replaced by the `chainLive` probe, Lesson 4).
|
|
50
|
+
|
|
51
|
+
Each finding flipped a "ship it" into a "revise first." The cost of catching them in review was a paragraph; the cost of shipping them would have been a framework that *claims* to self-improve on synthetic numbers — exactly the disease v7 set out to cure.
|
|
52
|
+
|
|
53
|
+
### The lesson
|
|
54
|
+
|
|
55
|
+
> A claim, even your own, is a hypothesis until something has tried to break it.
|
|
56
|
+
|
|
57
|
+
This is why Paradigm pairs a builder with a *reviewer*, and a designer with an *adversarial* pass. The self-audit found the holes; the adversarial review kept the *fixes* honest. v7 is the framework eating its own dog food — and the practice generalizes: anchor claims to evidence, then assign someone to falsify them before you build. The check is only worth running if it can fail.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: N-para-801-orchestration-emits-dag
|
|
3
|
+
title: 'Lesson 2: Orchestration Emits the DAG'
|
|
4
|
+
type: note
|
|
5
|
+
author: paradigm
|
|
6
|
+
created: '2026-06-13'
|
|
7
|
+
updated: '2026-06-13'
|
|
8
|
+
tags:
|
|
9
|
+
- course
|
|
10
|
+
- para-801
|
|
11
|
+
- close-the-loop
|
|
12
|
+
- orchestration
|
|
13
|
+
- agent-relay
|
|
14
|
+
symbols: []
|
|
15
|
+
difficulty: intermediate
|
|
16
|
+
estimatedMinutes: 7
|
|
17
|
+
prerequisites: []
|
|
18
|
+
category: paradigm-core
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## The Graph That Used to Be Thrown Away
|
|
22
|
+
|
|
23
|
+
When orchestration plans a multi-agent run, it computes a handoff graph: which agent goes first, which stages depend on which, how outputs flow forward. Before v7, that graph was *computed and then discarded* — the orchestration audit found it built at `orchestration.ts:1780-1830` and then dropped on the floor, with only a frozen `logOrchestration` blob recording `status: 'pending'` that nothing ever advanced.
|
|
24
|
+
|
|
25
|
+
This was the orchestration-to-task disconnect: the engine knew the shape of the work but never wrote it down anywhere the rest of the framework could see. v7 fixes this by having orchestration **emit the DAG as real tasks**.
|
|
26
|
+
|
|
27
|
+
## `emitTaskDag()`: Epic + Stage Children
|
|
28
|
+
|
|
29
|
+
In `execute` mode (and only `execute` — `plan` and `quick` emit nothing), orchestration now calls a new `emitTaskDag()` at the point it builds its stage prompts. It persists:
|
|
30
|
+
|
|
31
|
+
- **One epic task** — the orchestration root, with `claimant: orchestrator` and `external_ref: { kind: 'orchestration' }`.
|
|
32
|
+
- **One child task per stage-agent** — each carrying `parentTaskId` (the epic), its `stage` ordinal, `dependsOn` (the resolved handoff edges), and a `claimant: { kind: 'archetype', ref: <role> }`.
|
|
33
|
+
|
|
34
|
+
The frozen `status: 'pending'` blob is replaced by this live epic task. Emission **degrades gracefully**: if a task-write fails, the orchestration run still proceeds — emission is additive instrumentation, never a gate on the work.
|
|
35
|
+
|
|
36
|
+
## Status Flows Back
|
|
37
|
+
|
|
38
|
+
A DAG is only useful if the nodes' statuses stay current. v7 wires status back through the agents themselves: each spawned agent's prompt now carries its own `taskId` with instructions to flip the task to `in-progress` on start and `done` on finish (via `paradigm_task_update`). So the spine the orchestrator emits is the same spine the agents update as they work — and the same spine the learning loop settles on (Lesson 3).
|
|
39
|
+
|
|
40
|
+
> **v7.0 scope note:** loop-closure is scoped to the **MCP path** — the dominant Claude-Code-agent path where agents drive `paradigm_task_*`. The Symphony (Cursor/peer) status-flow-back watcher, which maps `metadata.task.taskId → updateTask`, is a fast-follow. The standalone CLI `orchestrate` binary emits no tasks in v7.0; a thin `task-bridge` adapter is the planned fast-follow. The spec states this cost plainly rather than claiming coverage the code does not have.
|
|
41
|
+
|
|
42
|
+
## The Typed Handoff: `AgentRelay`
|
|
43
|
+
|
|
44
|
+
The DAG emission rides on a second v7 cleanup: the **typed agent handoff**. Before v7, agents handed off to each other in free-text prose, and a hand-rolled regex parser (`parseFilePlan` / `parseFilePlanFromResponse`) tried to scrape structure back out of that prose. v7 deletes those regex parsers entirely and replaces the prose with one typed contract:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
interface AgentRelay {
|
|
48
|
+
taskId?: string;
|
|
49
|
+
agent: string;
|
|
50
|
+
status: string;
|
|
51
|
+
artifacts: string[];
|
|
52
|
+
decisions: string[];
|
|
53
|
+
handoffTo?: string;
|
|
54
|
+
handoffContext?: string;
|
|
55
|
+
filePlan?: string[]; // now a typed field, consumed directly
|
|
56
|
+
blockedOn?: string;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`TaskPayload` (the assignment) and `AgentRelay` (the completion) are the **request/response halves** of one exchange, kept separate and bound by an explicit map: `relay.taskId + status → updateTask`. Because `filePlan` is now a typed field, `planBuilderStages` consumes it directly — the brittle "parse my teammate's English" step is gone. Typed structure in, typed status out: that is the channel the loop closes over.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: N-para-801-settlement-closes-the-loop
|
|
3
|
+
title: 'Lesson 3: Settlement Closes the Loop'
|
|
4
|
+
type: note
|
|
5
|
+
author: paradigm
|
|
6
|
+
created: '2026-06-13'
|
|
7
|
+
updated: '2026-06-13'
|
|
8
|
+
tags:
|
|
9
|
+
- course
|
|
10
|
+
- para-801
|
|
11
|
+
- close-the-loop
|
|
12
|
+
- task-settlement
|
|
13
|
+
- learning-loop
|
|
14
|
+
symbols: []
|
|
15
|
+
difficulty: intermediate
|
|
16
|
+
estimatedMinutes: 8
|
|
17
|
+
prerequisites: []
|
|
18
|
+
category: paradigm-core
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## The Dead Joint
|
|
22
|
+
|
|
23
|
+
The learning loop was, in principle, a chain: a task finishes, the work is logged, a postflight pass extracts insights, and good insights are promoted into agent notebooks. In practice the audit found the very first link severed — `task_done` fed *nothing*. A task could complete and the learning chain would simply never run. Worse, the broken state looked exactly like the healthy state: no error, no missing file, just silence.
|
|
24
|
+
|
|
25
|
+
v7 closes this with a new module, `packages/paradigm-mcp/src/utils/task-settlement.ts`, and one function: `settleParentIfComplete(rootDir, parentTaskId)`.
|
|
26
|
+
|
|
27
|
+
## The Trigger: All Siblings Terminal
|
|
28
|
+
|
|
29
|
+
The original design fired settlement only on `done`. An adversarial review (Lesson 6) caught that this re-creates the open-loop bug: one `shelved` sibling, a `blocked` sibling, or a crashed run would leave the parent unsettled *forever*. The corrected trigger is **all-siblings-terminal**:
|
|
30
|
+
|
|
31
|
+
> When every task sharing a `parentTaskId` reaches a terminal state, the parent settles — exactly once.
|
|
32
|
+
|
|
33
|
+
The terminal set is a forward-compatible predicate (`{ done, shelved, crashed }` in v7.0). The settlement hook is placed **inside `updateTask`** — the real chokepoint — gated on `isTerminal(status) && parentTaskId`. Putting it there means `completeTask`, `shelveTask`, and any direct status set all fire settlement; none can drift. Idempotency is guaranteed by stamping `settledAt` once.
|
|
34
|
+
|
|
35
|
+
Two safety valves round it out:
|
|
36
|
+
- **A reaper** crashes abandoned `in-progress` tasks that are stale past a time window (default 30 minutes) whose run is no longer live — so a dead run cannot wedge a subtree open, and the liveness probe (Lesson 4) still sees it.
|
|
37
|
+
- **Orphan policy** — a child whose parent is missing self-settles and emits a `warn`.
|
|
38
|
+
|
|
39
|
+
## The Wired Chain
|
|
40
|
+
|
|
41
|
+
When a parent settles, it runs the learning chain — replacing every advisory-prose joint with a real call, in order:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
recordWorkLog → runPostflightLearning → autoPromoteJournalEntries
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
(In the MCP world this also threads Cid's debrief and `sessionInsights`.) This is the moment the loop *actually closes*: completed work becomes a work-log entry, the postflight pass turns verdict patterns into journal entries, and proven journal entries are promoted into notebooks the agents read next session.
|
|
48
|
+
|
|
49
|
+
## The Cid ↔ Loid Boundary
|
|
50
|
+
|
|
51
|
+
Settlement only ever writes `settledAt` and crash markers — **never live status**. This is the load-bearing ownership rule of v7:
|
|
52
|
+
|
|
53
|
+
> **Cid writes the present tense; Loid writes the past tense; they never co-write a field.**
|
|
54
|
+
|
|
55
|
+
- **Cid** (the Captain) writes `status` live-transitions, `claimant`, and the DAG edges at emission.
|
|
56
|
+
- **Loid** (intelligence officer) writes only `settledAt` — the retrospective trigger — plus everything in the learning stores (journals, notebooks, calibration). Loid is read-only on every other Task field.
|
|
57
|
+
|
|
58
|
+
The dependency arrow points one way: `status → settlement → learning`. Settlement never calls back to change status. That one-way arrow is why the loop can close without two owners fighting over the same field — and it is the boundary the whole self-improving claim rests on.
|
|
59
|
+
|
|
60
|
+
## Honest Confidence, Not Synthetic Belief-Deltas
|
|
61
|
+
|
|
62
|
+
The settlement chain feeds notebook promotion, which gates on confidence. v7 made one honest cut here. The original plan promoted on a **belief-delta** (`confidence_after − confidence_before ≥ 0.15`), but the adversarial review proved both numbers were branch literals — promoting on the *difference of two constants* is numerology.
|
|
63
|
+
|
|
64
|
+
v7.0's fix: keep the existing absolute `≥ 0.8` promotion gate, but make `confidence_after` **real** — agents emit an optional `confidence` value that `runPostflightLearning` prefers, falling back to the old literal only when absent. `confidence_before` stays in the type, now explicitly marked *not gated on*. The belief-delta gate is honestly deferred to v7.x (a real pre-task prior needs unbuilt elicitation infrastructure). Honest absolute-confidence learning now; belief-movement learning later — designed honestly rather than shipped on synthetic numbers.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: N-para-801-the-task-dag
|
|
3
|
+
title: 'Lesson 1: The Spine — A Claimant-Owned Task DAG'
|
|
4
|
+
type: note
|
|
5
|
+
author: paradigm
|
|
6
|
+
created: '2026-06-13'
|
|
7
|
+
updated: '2026-06-13'
|
|
8
|
+
tags:
|
|
9
|
+
- course
|
|
10
|
+
- para-801
|
|
11
|
+
- close-the-loop
|
|
12
|
+
- task-dag
|
|
13
|
+
- claimant
|
|
14
|
+
symbols: []
|
|
15
|
+
difficulty: intermediate
|
|
16
|
+
estimatedMinutes: 8
|
|
17
|
+
prerequisites: []
|
|
18
|
+
category: paradigm-core
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Why v7 Exists: Recording vs. Verifying
|
|
22
|
+
|
|
23
|
+
Before v7, Paradigm *recorded that it was asked to do the right thing — but it did not verify that it did.* A two-slice self-audit (first the task system, then the orchestration engine) proved this with file-and-line evidence: the classifier misrouted silently, the best agents were not routable, the learning loop's broken state was byte-identical to its healthy state, enforcement checked invocation rather than work, and the Captain owned nothing.
|
|
24
|
+
|
|
25
|
+
v7 — "Close the Loop" — makes the framework's own value proposition **true instead of asserted**. It does this with one keystone primitive:
|
|
26
|
+
|
|
27
|
+
> A persisted, symbol-bound, **claimant-owned task DAG** that orchestration emits, whose completion feeds the learning loop, and which Cid the Captain manages.
|
|
28
|
+
|
|
29
|
+
One primitive closes four problems at once: the open learning loop, the orchestration-to-task disconnect, Cid's inertness, and the unfalsifiability of "self-improving." This lesson covers the keystone itself — the Spine. (Decision **TD-2026-06-13-718**; design in `docs/specs/v7-close-the-loop.md`.)
|
|
30
|
+
|
|
31
|
+
## The New Task Schema
|
|
32
|
+
|
|
33
|
+
The `Task` interface in `packages/paradigm-mcp/src/utils/task-loader.ts` gained four families of fields in v7:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
export type ClaimantKind = 'archetype' | 'human' | 'peer';
|
|
37
|
+
export interface Claimant { kind: ClaimantKind; ref: string; }
|
|
38
|
+
|
|
39
|
+
export type TaskStatus =
|
|
40
|
+
| 'open' | 'in-progress' | 'done' | 'shelved'; // v7.0 ships 4 states
|
|
41
|
+
|
|
42
|
+
export interface Task {
|
|
43
|
+
id: string; created: string; // immutable
|
|
44
|
+
blurb: string; priority: 'high'|'medium'|'low'; status: TaskStatus; tags: string[];
|
|
45
|
+
claimant?: Claimant; // typed claim — NOT a name string
|
|
46
|
+
parentTaskId?: string; dependsOn?: string[]; stage?: number; // DAG edges
|
|
47
|
+
started_at?: string; completed?: string; settledAt?: string; // lifecycle stamps
|
|
48
|
+
external_ref?: ExternalRef; // renamed from orphan session_link
|
|
49
|
+
related_lore?: string[];
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## The Claimant: A Typed Claim, Not a Name Tag
|
|
54
|
+
|
|
55
|
+
The single most important design decision in the Spine is that ownership is a **tagged union**, not a flat assignee string:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
{ kind: 'archetype', ref: 'builder' } // a role on the roster
|
|
59
|
+
{ kind: 'human', ref: 'matt@…' } // a git user / email
|
|
60
|
+
{ kind: 'peer', ref: 'agent-7' } // a Symphony peer agentId
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
A flat `assignee: "builder"` string cannot answer the questions the learning loop needs to ask. Is "builder" a role that any instance can fill, a specific human, or a remote peer? Those three carry completely different meaning:
|
|
64
|
+
|
|
65
|
+
- **Archetype-fit signal** (v7.x analytics): comparing the *predicted* owner (`kind: archetype`) against the *closing* owner tells you whether auto-routing picked the right specialist.
|
|
66
|
+
- **Reassignment-churn detection**: three claimant rewrites before a task settles flags a `spec-clarity` antipattern — the blurb was under-specified. But a *healthy* peer handoff (`kind: peer`) must be distinguished from churn, and only the typed `kind` lets you tell them apart.
|
|
67
|
+
|
|
68
|
+
A name tag throws away the very distinction the loop is built to learn from. The typed claim is the difference between "someone touched this" and "this kind of owner closed this kind of work."
|
|
69
|
+
|
|
70
|
+
## DAG Edges Without a Database
|
|
71
|
+
|
|
72
|
+
The DAG is stored as an **edge-list-in-node**: each task's own YAML carries its `parentTaskId`, `dependsOn`, and `stage`. The graph is reconstructed simply by loading the node set — **no separate edges file, no SQLite.** This survives the existing date-partitioned task loader with zero loader changes, and cross-date edges still work because every task id embeds its date.
|
|
73
|
+
|
|
74
|
+
- `parentTaskId` — points at the **epic** (the orchestration root) this stage child belongs to.
|
|
75
|
+
- `dependsOn` — the resolved handoff edges (this stage waits on those stages).
|
|
76
|
+
- `stage` — the ordinal position in the topologically-sorted handoff graph.
|
|
77
|
+
|
|
78
|
+
## The `in-progress` Status and the State Machine
|
|
79
|
+
|
|
80
|
+
v7.0 ships **four** states (`open | in-progress | done | shelved`); `claimed` and `blocked` are deferred to a fast-follow because they are justified only by Symphony peer-claims, which are themselves fast-follow. The transitions are enforced by a single `assertTransition` guard inside `updateTask`:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
open → in-progress | done | shelved
|
|
84
|
+
in-progress → done | open | shelved
|
|
85
|
+
shelved → open
|
|
86
|
+
done → (terminal)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`started_at` is stamped the moment a task enters `in-progress`. `settledAt` is stamped only by the learning loop (covered in Lesson 3) — never by live status writes. That single ownership rule, "live state is written by one owner; the settlement stamp by another," is what keeps the loop honest.
|
|
90
|
+
|
|
91
|
+
## Additive, Lazy-Healing Migration
|
|
92
|
+
|
|
93
|
+
Every v7 field is **optional**, so old task YAML loads unchanged. The orphaned `session_link` field is healed into the typed `external_ref` by a read-side `normalizeTask` shim at the load chokepoint — files migrate on their next write, with no bulk migration step. MCP tool enums *widen* (non-breaking). The task system also gained its **first tests ever** in v7 — the audit found zero, and the Spine ships with 23 unit tests.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
id: LP-para-801
|
|
2
|
+
title: 'PARA 801: Closing the Loop (v7)'
|
|
3
|
+
description: "Learn how Paradigm v7 makes the framework's own checks TRUE instead of asserted — by closing the orchestration and learning loop around one keystone: a persisted, claimant-owned task DAG that orchestration emits, settlement feeds back as learning, and Cid the Captain manages."
|
|
4
|
+
author: paradigm
|
|
5
|
+
created: '2026-06-13'
|
|
6
|
+
updated: '2026-06-13'
|
|
7
|
+
tags:
|
|
8
|
+
- course
|
|
9
|
+
- para-801
|
|
10
|
+
- close-the-loop
|
|
11
|
+
ordered: true
|
|
12
|
+
category: paradigm-core
|
|
13
|
+
steps:
|
|
14
|
+
- content: N-para-801-the-task-dag
|
|
15
|
+
required: true
|
|
16
|
+
- content: Q-para-801-the-task-dag
|
|
17
|
+
required: true
|
|
18
|
+
passRequired: true
|
|
19
|
+
- content: N-para-801-orchestration-emits-dag
|
|
20
|
+
required: true
|
|
21
|
+
- content: Q-para-801-orchestration-emits-dag
|
|
22
|
+
required: true
|
|
23
|
+
passRequired: true
|
|
24
|
+
- content: N-para-801-settlement-closes-the-loop
|
|
25
|
+
required: true
|
|
26
|
+
- content: Q-para-801-settlement-closes-the-loop
|
|
27
|
+
required: true
|
|
28
|
+
passRequired: true
|
|
29
|
+
- content: N-para-801-falsifiable-self-improvement
|
|
30
|
+
required: true
|
|
31
|
+
- content: Q-para-801-falsifiable-self-improvement
|
|
32
|
+
required: true
|
|
33
|
+
passRequired: true
|
|
34
|
+
- content: N-para-801-cid-becomes-real
|
|
35
|
+
required: true
|
|
36
|
+
- content: Q-para-801-cid-becomes-real
|
|
37
|
+
required: true
|
|
38
|
+
passRequired: true
|
|
39
|
+
- content: N-para-801-honest-routing-and-the-method
|
|
40
|
+
required: true
|
|
41
|
+
- content: Q-para-801-honest-routing-and-the-method
|
|
42
|
+
required: true
|
|
43
|
+
passRequired: true
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
id: Q-para-801-cid-becomes-real
|
|
2
|
+
title: 'PARA 801: Closing the Loop — Lesson 5: Cid the Captain Becomes Real'
|
|
3
|
+
description: 'Quiz for lesson: Cid the Captain Becomes Real'
|
|
4
|
+
author: paradigm
|
|
5
|
+
created: '2026-06-13'
|
|
6
|
+
updated: '2026-06-13'
|
|
7
|
+
tags:
|
|
8
|
+
- course
|
|
9
|
+
- para-801
|
|
10
|
+
symbols: []
|
|
11
|
+
difficulty: intermediate
|
|
12
|
+
passThreshold: 0.7
|
|
13
|
+
category: paradigm-core
|
|
14
|
+
questions:
|
|
15
|
+
- id: q1
|
|
16
|
+
question: What durable artifact does paradigm_captain_board give Cid, and what are its actions?
|
|
17
|
+
choices:
|
|
18
|
+
A: A read-only console log; no actions
|
|
19
|
+
B: The live run-DAG (epic tasks with stage children ordered by dependsOn, plus ripple-ranked unclaimed) with actions read | claim | advance — Cid's and only Cid's write path for claimant, live status, and runStatus
|
|
20
|
+
C: A portal.yaml editor; actions add-gate | remove-gate
|
|
21
|
+
D: 'A notebook of past learnings; action: promote'
|
|
22
|
+
E: A SQLite dashboard with no write path
|
|
23
|
+
correct: B
|
|
24
|
+
explanation: 'paradigm_captain_board gives Cid an owned read+write artifact. `read` assembles the live run-DAG — epics with stage children ordered by dependsOn, plus ripple-ranked unclaimed — exactly what the Conductor task-dashboard renders. `claim` and `advance` are Cid''s and only Cid''s write path for claimant, live status transitions, and run-record runStatus. The audit''s "the Captain owns nothing" finding is resolved by giving him a board to write.'
|
|
25
|
+
- id: q2
|
|
26
|
+
question: At session-open, what does Cid now do that constitutes a real per-session mutation (replacing the old anonymous task dump)?
|
|
27
|
+
choices:
|
|
28
|
+
A: Nothing — session-open is still a static dump
|
|
29
|
+
B: He runs the reaper, reads the board, ranks unclaimed by ripple-risk, and proposes claimants by *writing* claimant and advancing open→claimed; that write is the durable proof the Captain did something (human/peer claims override his proposals)
|
|
30
|
+
C: He deletes all open tasks
|
|
31
|
+
D: He emails the roster to the user
|
|
32
|
+
E: He rebuilds the SQLite index
|
|
33
|
+
correct: B
|
|
34
|
+
explanation: 'Session-open replaces the anonymous static task dump with a Cid-attributed board read: he runs the reaper, ranks unclaimed tasks by ripple-risk, surfaces the top few, and proposes claimants by writing `claimant` and advancing open→claimed. That write is the durable proof the Captain acted this session. Human or peer claims override an archetype proposal, and a failed board read falls back safely to the plain list.'
|
|
35
|
+
- id: q3
|
|
36
|
+
question: 'At session-close, the learning chain didn''t run. What does Cid do — and what does he deliberately NOT do?'
|
|
37
|
+
choices:
|
|
38
|
+
A: He hard-blocks the session with a guard block until the human fixes the loop
|
|
39
|
+
B: He self-heals by running postflight himself rather than blocking; if self-heal throws he proposes only an `advise` block — never `guard`, because a learning-loop gap must not deadlock a human (hard refuse is reserved for correctness gates like a missing .purpose)
|
|
40
|
+
C: He silently ignores it and writes .cid-briefed unconditionally as before
|
|
41
|
+
D: He benches Loid
|
|
42
|
+
E: He deletes the settlement records
|
|
43
|
+
correct: B
|
|
44
|
+
explanation: 'An early design had Cid refuse to finish the session if postflight hadn''t run — the adversarial review flagged this as a user-facing deadlock (blocking a human over a *learning* step inverts priorities). The fix: Cid reads the chainLive probe, self-heals by running postflight himself, and if self-heal itself throws he proposes only an `advise` block (severity advise, never guard). Hard refuse stays reserved for correctness gates, never learning-loop liveness.'
|
|
45
|
+
- id: q4
|
|
46
|
+
question: The Cid↔Loid boundary is summarized in terms of tense. Which mapping is correct?
|
|
47
|
+
choices:
|
|
48
|
+
A: Cid writes settledAt and notebooks; Loid writes live status and claimant
|
|
49
|
+
B: Cid writes the present tense (live status, claimant, DAG edges at emission, runStatus); Loid writes the past tense (settledAt and the learning stores); they never co-write a field
|
|
50
|
+
C: Both write status; neither writes settledAt
|
|
51
|
+
D: Cid and Loid both write settledAt for redundancy
|
|
52
|
+
E: Loid writes everything; Cid is read-only
|
|
53
|
+
correct: B
|
|
54
|
+
explanation: 'Tense is the mnemonic: Cid writes the present tense — live `status` transitions (up to but not including the work-completer''s done), `claimant`, DAG edges at emission, and run-record runStatus (what is happening now). Loid writes the past tense — `settledAt` and the learning stores (what we learned from what already happened). They never co-write a field, and the dependency points one way: status → settlement → learning.'
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
id: Q-para-801-falsifiable-self-improvement
|
|
2
|
+
title: 'PARA 801: Closing the Loop — Lesson 4: Falsifiable Self-Improvement'
|
|
3
|
+
description: 'Quiz for lesson: Falsifiable Self-Improvement'
|
|
4
|
+
author: paradigm
|
|
5
|
+
created: '2026-06-13'
|
|
6
|
+
updated: '2026-06-13'
|
|
7
|
+
tags:
|
|
8
|
+
- course
|
|
9
|
+
- para-801
|
|
10
|
+
symbols: []
|
|
11
|
+
difficulty: intermediate
|
|
12
|
+
passThreshold: 0.7
|
|
13
|
+
category: paradigm-core
|
|
14
|
+
questions:
|
|
15
|
+
- id: q1
|
|
16
|
+
question: Why was the JPS (journals-per-settlement) metric rejected as a measure of whether the learning loop is alive?
|
|
17
|
+
choices:
|
|
18
|
+
A: It was too expensive to compute over a trailing window
|
|
19
|
+
B: It was circular — a clean run that legitimately produced no insight ("silence is signal") and a severed chain both yield JPS = 0, so it could not distinguish healthy quiet from a dead pipe
|
|
20
|
+
C: It double-counted journal entries
|
|
21
|
+
D: It required SQLite
|
|
22
|
+
E: It only worked in the CLI world
|
|
23
|
+
correct: B
|
|
24
|
+
explanation: 'JPS measures the *volume of output*, which cannot tell you whether the *pipe* is alive. A clean settlement that had nothing new to promote and a settlement whose chain was severed both produce JPS = 0. The metric could not separate healthy silence from a corpse, so v7 replaced it with the chainLive probe that instruments the pipe instead of the output.'
|
|
25
|
+
- id: q2
|
|
26
|
+
question: How does the chainLive liveness probe make "self-improving" falsifiable?
|
|
27
|
+
choices:
|
|
28
|
+
A: It counts how many notebooks exist
|
|
29
|
+
B: Each settlement appends a settlement-liveness.jsonl record with per-stage ok|threw|skipped (written in a finally so a mid-chain throw still records which stage died) and chainLive=true only if every non-skipped stage ran; a doctor check alarms on chainLive=false, which a reviewer can trigger by commenting out a stage
|
|
30
|
+
C: It asks the user to self-report whether they felt the framework improved
|
|
31
|
+
D: It measures token spend per session
|
|
32
|
+
E: It is not falsifiable; it just logs activity
|
|
33
|
+
correct: B
|
|
34
|
+
explanation: 'Each settlement writes a record to .paradigm/events/settlement-liveness.jsonl with each stage marked ok|threw|skipped, written in a finally block so a mid-chain throw still records *which* stage died. chainLive is true only if every non-skipped stage returned ok. A paradigm doctor / paradigm:health check alarms on chainLive=false — and a reviewer can comment out runPostflightLearning, settle once, and watch the check flip red naming the dead stage. That deliberate-break-turns-red property is what makes the claim falsifiable.'
|
|
35
|
+
- id: q3
|
|
36
|
+
question: 'A settlement records `chainLive: true, journalsWritten: 0`. What does this mean?'
|
|
37
|
+
choices:
|
|
38
|
+
A: The chain is broken — zero journals means a dead pipe
|
|
39
|
+
B: The pipe ran end-to-end successfully and simply had nothing new to promote — a healthy clean subtree ("silence is signal"); this is distinguishable from chainLive=false, which is the broken case
|
|
40
|
+
C: The settlement never ran
|
|
41
|
+
D: The agent crashed mid-task
|
|
42
|
+
E: Postflight was skipped intentionally by the user
|
|
43
|
+
correct: B
|
|
44
|
+
explanation: 'chainLive=true means every non-skipped stage ran without throwing — the pipe is alive. journalsWritten=0 is diagnostic only: it means there was nothing new worth promoting this time (silence is signal). This is precisely the case JPS could not distinguish from a dead chain; the chainLive probe separates healthy quiet (chainLive=true, journals=0) from a severed chain (chainLive=false).'
|
|
45
|
+
- id: q4
|
|
46
|
+
question: 'The chainLive design generalizes into a pattern for honest self-checks. Which principle best captures it?'
|
|
47
|
+
choices:
|
|
48
|
+
A: Measure the volume of results; more output means a healthier system
|
|
49
|
+
B: Instrument the pipe (liveness of the mechanism, falsifiable) not the output (volume, not falsifiable); record per-stage in a finally; and make the red state reachable by a deliberate act
|
|
50
|
+
C: Trust the agent's self-assessment of its own improvement
|
|
51
|
+
D: Only check the loop on a fixed schedule, never per settlement
|
|
52
|
+
E: Replace all checks with a single boolean the user sets manually
|
|
53
|
+
correct: B
|
|
54
|
+
explanation: 'The generalizable pattern: (1) instrument the pipe, not the output — liveness of the mechanism is falsifiable, volume of results is not; (2) record per-stage in a finally so a mid-pipe failure still tells you where it died; (3) make the red state reachable by a deliberate act — if you cannot describe the exact change that turns the check red, the check is not really checking anything. A self-improving claim is only earned if you can prove it ISN''T improving when it breaks.'
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
id: Q-para-801-honest-routing-and-the-method
|
|
2
|
+
title: 'PARA 801: Closing the Loop — Lesson 6: Honest Routing & the Dogfood Method'
|
|
3
|
+
description: 'Quiz for lesson: Honest Routing & the Dogfood Method'
|
|
4
|
+
author: paradigm
|
|
5
|
+
created: '2026-06-13'
|
|
6
|
+
updated: '2026-06-13'
|
|
7
|
+
tags:
|
|
8
|
+
- course
|
|
9
|
+
- para-801
|
|
10
|
+
symbols: []
|
|
11
|
+
difficulty: intermediate
|
|
12
|
+
passThreshold: 0.7
|
|
13
|
+
category: paradigm-core
|
|
14
|
+
questions:
|
|
15
|
+
- id: q1
|
|
16
|
+
question: 'What was the "bugfix poison-pill" the v7 classifier rebuild removed?'
|
|
17
|
+
choices:
|
|
18
|
+
A: A bug that crashed orchestration on the word "fix"
|
|
19
|
+
B: An audit of a *broken* system used to route to [security, builder] — the word "broken" silently summoned a fixer; new audit/design/research families now map to read-only analyst rosters that never route to a fixer
|
|
20
|
+
C: A poisoned npm dependency
|
|
21
|
+
D: A SQL injection in the classifier
|
|
22
|
+
E: A hardcoded agent that always won
|
|
23
|
+
correct: B
|
|
24
|
+
explanation: 'The keyword classifier conflated *analyzing* a broken system with *fixing* it: an audit request containing "broken" routed to [security, builder], silently summoning an implementer. v7 rebuilt the classifier as confidence-scored with intent-verb anchoring, and new audit/design/research families map to read-only analyst rosters that never route to a fixer. Asking for analysis no longer triggers implementation.'
|
|
25
|
+
- id: q2
|
|
26
|
+
question: 'Besides fixing classification, what did v7 change about which agents auto-orchestration can reach?'
|
|
27
|
+
choices:
|
|
28
|
+
A: It removed all specialist agents to simplify routing
|
|
29
|
+
B: The trigger-based agent-matcher becomes the primary roster source, so previously-unroutable specialists (product/North, forge/Loid, researcher/Scout, dx/Helix) can now be assembled automatically — not only by a human naming them
|
|
30
|
+
C: It made every agent require manual selection
|
|
31
|
+
D: It limited orchestration to exactly three agents
|
|
32
|
+
E: Nothing — routability was already complete
|
|
33
|
+
correct: B
|
|
34
|
+
explanation: 'An audit finding was that the best agents were not routable by auto-orchestration. v7 makes the trigger-based agent-matcher the primary roster/suggestion source, so specialists like product (North), forge (Loid), researcher (Scout), and dx (Helix) can be assembled automatically. A team you cannot reach is a team you do not have.'
|
|
35
|
+
- id: q3
|
|
36
|
+
question: 'The v7 "dogfood method" had two stages. What were they, and what discipline anchored the first?'
|
|
37
|
+
choices:
|
|
38
|
+
A: Brainstorm then vote; anchored by consensus
|
|
39
|
+
B: A two-slice self-audit anchored by file-and-line evidence (not vibes), followed by an adversarial review that tried to break the design against the real code before it was built
|
|
40
|
+
C: Write code then test; anchored by coverage percentage
|
|
41
|
+
D: Survey users then ship; anchored by NPS
|
|
42
|
+
E: Design then document; anchored by word count
|
|
43
|
+
correct: B
|
|
44
|
+
explanation: 'Stage 1 was a two-slice self-audit (task system, then the orchestration engine) disciplined by file-and-line evidence — "the loop is broken" is a vibe; "task_done feeds nothing, here is the dead joint" is a finding. Stage 2 was an adversarial review whose job was to *break* the design against the real code before building it — treating even the team''s own spec as a hypothesis, not a fact.'
|
|
45
|
+
- id: q4
|
|
46
|
+
question: 'The adversarial review caught three keystone claims as false or circular. Which trio is correct?'
|
|
47
|
+
choices:
|
|
48
|
+
A: Missing tests, slow loader, and a typo in portal.yaml
|
|
49
|
+
B: The belief-delta gate ran on hardcoded confidence numbers; "both worlds flow through completeTask" was false (the CLI orchestrator emits no tasks); and the JPS metric was circular
|
|
50
|
+
C: The DAG used SQLite, the reaper never fired, and Cid hard-blocked sessions
|
|
51
|
+
D: The classifier was too slow, agents were unroutable, and notebooks were empty
|
|
52
|
+
E: There were no false claims; all three were confirmed correct
|
|
53
|
+
correct: B
|
|
54
|
+
explanation: 'The adversarial pass caught three keystone wiring claims false-or-circular against the real code: (1) the belief-delta gate ran on hardcoded branch-literal confidence numbers; (2) "both worlds flow through completeTask" was false — the CLI orchestrator emits no tasks, so scope was honestly narrowed to the MCP path; (3) JPS was circular — clean work and a dead chain both read zero. Each flipped a "ship it" into a "revise first." The generalizable lesson: a claim, even your own, is a hypothesis until something has tried to break it.'
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
id: Q-para-801-orchestration-emits-dag
|
|
2
|
+
title: 'PARA 801: Closing the Loop — Lesson 2: Orchestration Emits the DAG'
|
|
3
|
+
description: 'Quiz for lesson: Orchestration Emits the DAG'
|
|
4
|
+
author: paradigm
|
|
5
|
+
created: '2026-06-13'
|
|
6
|
+
updated: '2026-06-13'
|
|
7
|
+
tags:
|
|
8
|
+
- course
|
|
9
|
+
- para-801
|
|
10
|
+
symbols: []
|
|
11
|
+
difficulty: intermediate
|
|
12
|
+
passThreshold: 0.7
|
|
13
|
+
category: paradigm-core
|
|
14
|
+
questions:
|
|
15
|
+
- id: q1
|
|
16
|
+
question: Before v7, what happened to the handoff graph that orchestration computed for a multi-agent run?
|
|
17
|
+
choices:
|
|
18
|
+
A: It was persisted as tasks and tracked to completion
|
|
19
|
+
B: 'It was computed and then discarded — only a frozen `status: pending` blob was logged, which nothing ever advanced'
|
|
20
|
+
C: It was written to portal.yaml
|
|
21
|
+
D: It was emailed to the user for approval
|
|
22
|
+
E: It was stored as a SQLite graph
|
|
23
|
+
correct: B
|
|
24
|
+
explanation: 'The orchestration audit found the handoff graph computed (around `orchestration.ts:1780-1830`) and then dropped, with only a frozen `logOrchestration` `status: pending` blob recorded and never advanced. This was the orchestration-to-task disconnect v7 fixes — orchestration now emits the graph as real tasks via `emitTaskDag()`.'
|
|
25
|
+
- id: q2
|
|
26
|
+
question: What does `emitTaskDag()` persist, and in which orchestration mode?
|
|
27
|
+
choices:
|
|
28
|
+
A: One flat task per run, in every mode
|
|
29
|
+
B: One epic task (claimant orchestrator, external_ref orchestration) plus one child per stage-agent (parentTaskId, stage, dependsOn, archetype claimant) — in execute mode only
|
|
30
|
+
C: A child task per file edited, in plan mode
|
|
31
|
+
D: Nothing — it only logs to the console
|
|
32
|
+
E: A full SQLite snapshot in quick mode
|
|
33
|
+
correct: B
|
|
34
|
+
explanation: 'In `execute` mode only (plan and quick emit nothing), `emitTaskDag()` persists one epic task — the orchestration root with `claimant: orchestrator` and `external_ref: { kind: orchestration }` — plus one child task per stage-agent carrying parentTaskId, stage, dependsOn, and a `{ kind: archetype }` claimant. Emission degrades gracefully if a write fails; it never gates the work.'
|
|
35
|
+
- id: q3
|
|
36
|
+
question: In v7.0, how does a stage task's status flow back as the agent works, and what is the scope caveat?
|
|
37
|
+
choices:
|
|
38
|
+
A: A background daemon polls the filesystem; all execution paths are covered equally
|
|
39
|
+
B: Each spawned agent's prompt carries its taskId with instructions to flip in-progress/done via paradigm_task_update; v7.0 scopes loop-closure to the MCP path, with Symphony and CLI flow-back as fast-follows
|
|
40
|
+
C: The orchestrator marks everything done at the end regardless of agent output
|
|
41
|
+
D: Status never flows back; the DAG is write-once
|
|
42
|
+
E: Status flows back only through Git hooks
|
|
43
|
+
correct: B
|
|
44
|
+
explanation: 'v7 threads each agent''s taskId into its prompt with instructions to flip in-progress on start and done on finish via paradigm_task_update. v7.0 honestly scopes loop-closure to the dominant MCP (Claude-Code-agent) path; the Symphony/Cursor watcher and the standalone CLI orchestrate binary''s task-bridge are stated as fast-follows rather than claimed as covered.'
|
|
45
|
+
- id: q4
|
|
46
|
+
question: What did the typed `AgentRelay` contract replace, and what was deleted as a result?
|
|
47
|
+
choices:
|
|
48
|
+
A: It replaced portal.yaml; the gates were deleted
|
|
49
|
+
B: It replaced free-text prose handoffs between stages; the hand-rolled regex parsers (parseFilePlan / parseFilePlanFromResponse) were deleted, and planBuilderStages now consumes the typed filePlan field directly
|
|
50
|
+
C: It replaced the task loader; the YAML store was deleted
|
|
51
|
+
D: It replaced SQLite; the database was deleted
|
|
52
|
+
E: Nothing was deleted — AgentRelay is purely additive logging
|
|
53
|
+
correct: B
|
|
54
|
+
explanation: 'AgentRelay is a typed completion contract (artifacts, decisions, handoffTo, filePlan, blockedOn). It replaces the free-text prose handoff and lets v7 delete the brittle regex parsers that used to scrape structure out of that prose — planBuilderStages now reads the typed `filePlan` field directly. TaskPayload (assignment) and AgentRelay (completion) are the request/response halves, bound by `relay.taskId + status → updateTask`.'
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
id: Q-para-801-settlement-closes-the-loop
|
|
2
|
+
title: 'PARA 801: Closing the Loop — Lesson 3: Settlement Closes the Loop'
|
|
3
|
+
description: 'Quiz for lesson: Settlement Closes the Loop'
|
|
4
|
+
author: paradigm
|
|
5
|
+
created: '2026-06-13'
|
|
6
|
+
updated: '2026-06-13'
|
|
7
|
+
tags:
|
|
8
|
+
- course
|
|
9
|
+
- para-801
|
|
10
|
+
symbols: []
|
|
11
|
+
difficulty: intermediate
|
|
12
|
+
passThreshold: 0.7
|
|
13
|
+
category: paradigm-core
|
|
14
|
+
questions:
|
|
15
|
+
- id: q1
|
|
16
|
+
question: What is the settlement trigger in v7 — when does a parent task settle and run the learning chain?
|
|
17
|
+
choices:
|
|
18
|
+
A: As soon as the first child reaches `done`
|
|
19
|
+
B: When every sibling sharing the parentTaskId reaches a terminal state (all-siblings-terminal) — exactly once, idempotent via settledAt
|
|
20
|
+
C: On a fixed 30-minute timer regardless of child status
|
|
21
|
+
D: Only when the human manually calls settle
|
|
22
|
+
E: When the parent task itself is marked done by hand
|
|
23
|
+
correct: B
|
|
24
|
+
explanation: 'Settlement fires on all-siblings-terminal: when every task sharing a parentTaskId reaches a terminal state ({done, shelved, crashed} in v7.0), the parent settles exactly once, made idempotent by stamping settledAt. The original design fired only on `done`, which the adversarial review caught as re-creating the open-loop bug — one shelved or crashed sibling would leave the parent unsettled forever.'
|
|
25
|
+
- id: q2
|
|
26
|
+
question: Where is the settlement hook placed, and why there?
|
|
27
|
+
choices:
|
|
28
|
+
A: Only inside completeTask, so done is the only path that settles
|
|
29
|
+
B: Inside updateTask (the real chokepoint), gated on isTerminal(status) && parentTaskId — so completeTask, shelveTask, and any direct status set all fire it and none can drift
|
|
30
|
+
C: In a Git post-commit hook
|
|
31
|
+
D: In the orchestrator's plan mode
|
|
32
|
+
E: In the Stop hook only
|
|
33
|
+
correct: B
|
|
34
|
+
explanation: 'The hook lives inside updateTask — the real chokepoint — gated on isTerminal(status) && parentTaskId. Putting it at the chokepoint (rather than in completeTask alone) means completeTask, shelveTask, and direct status sets all settle, with no path able to drift. A reaper also crashes abandoned in-progress tasks stale past a window, and orphans (missing parent) self-settle with a warn.'
|
|
35
|
+
- id: q3
|
|
36
|
+
question: 'The v7 thesis is "Cid writes the present tense; Loid writes the past tense; they never co-write a field." Which field does settlement write, holding that boundary?'
|
|
37
|
+
choices:
|
|
38
|
+
A: Settlement writes `status` live-transitions
|
|
39
|
+
B: Settlement writes `claimant`
|
|
40
|
+
C: Settlement only ever writes settledAt (and crash markers) — never live status; Cid owns live status/claimant/edges, Loid owns settledAt and the learning stores
|
|
41
|
+
D: Settlement writes the DAG edges
|
|
42
|
+
E: Settlement co-writes status and settledAt together
|
|
43
|
+
correct: C
|
|
44
|
+
explanation: 'Settlement writes only settledAt and crash markers, never live status. This holds the load-bearing Cid↔Loid boundary: Cid (present tense) writes status live-transitions, claimant, and the DAG edges at emission; Loid (past tense) writes settledAt and the learning stores. The dependency points one way — status → settlement → learning — and settlement never calls back to change status.'
|
|
45
|
+
- id: q4
|
|
46
|
+
question: 'Why did v7.0 drop the original belief-delta promotion gate (confidence_after − confidence_before ≥ 0.15) in favor of keeping the absolute ≥ 0.8 gate with a *real* confidence_after?'
|
|
47
|
+
choices:
|
|
48
|
+
A: The delta gate was too slow to compute
|
|
49
|
+
B: Both confidence numbers were hardcoded branch literals, so a delta gate promotes on the difference of two constants (numerology); v7.0 keeps the absolute gate but makes confidence_after a real agent output, deferring the belief-delta honestly to v7.x
|
|
50
|
+
C: The team preferred round numbers
|
|
51
|
+
D: Belief-deltas are mathematically impossible
|
|
52
|
+
E: The absolute gate was removed entirely and replaced by manual approval
|
|
53
|
+
correct: B
|
|
54
|
+
explanation: 'The adversarial review proved both confidence_before and confidence_after were branch literals, so promoting on their difference is numerology. v7.0''s honest fix: keep the existing absolute ≥0.8 gate but make confidence_after real (agents emit an optional `confidence` that runPostflightLearning prefers, falling back to the literal only when absent). confidence_before stays, explicitly marked not-gated-on; the belief-delta gate is deferred to v7.x because a real pre-task prior needs unbuilt elicitation infrastructure.'
|