@warpgogol/forge 5.3.4 → 6.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/CHANGELOG.md +8 -0
- package/bin/cli.ts +7 -2
- package/dist/bin/cli.js +7 -2
- package/dist/bin/cli.js.map +1 -1
- package/dist/os/adr/adr.module.d.ts.map +1 -1
- package/dist/os/adr/adr.module.js +2 -0
- package/dist/os/adr/adr.module.js.map +1 -1
- package/dist/os/audit/audit.module.d.ts.map +1 -1
- package/dist/os/audit/audit.module.js +2 -0
- package/dist/os/audit/audit.module.js.map +1 -1
- package/dist/os/compass/compass.module.d.ts.map +1 -1
- package/dist/os/compass/compass.module.js +47 -15
- package/dist/os/compass/compass.module.js.map +1 -1
- package/dist/os/compass/handlers/compass-audit-handler.d.ts +2 -0
- package/dist/os/compass/handlers/compass-audit-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-audit-handler.js +39 -9
- package/dist/os/compass/handlers/compass-audit-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-docs-validate.d.ts +13 -0
- package/dist/os/compass/handlers/compass-docs-validate.d.ts.map +1 -0
- package/dist/os/compass/handlers/compass-docs-validate.js +326 -0
- package/dist/os/compass/handlers/compass-docs-validate.js.map +1 -0
- package/dist/os/compass/handlers/summary-record.d.ts +11 -2
- package/dist/os/compass/handlers/summary-record.d.ts.map +1 -1
- package/dist/os/compass/handlers/summary-record.js +93 -5
- package/dist/os/compass/handlers/summary-record.js.map +1 -1
- package/dist/os/core/core.module.d.ts.map +1 -1
- package/dist/os/core/core.module.js +124 -73
- package/dist/os/core/core.module.js.map +1 -1
- package/dist/os/exploration/exploration.module.d.ts.map +1 -1
- package/dist/os/exploration/exploration.module.js +3 -0
- package/dist/os/exploration/exploration.module.js.map +1 -1
- package/dist/os/naming/naming.module.d.ts.map +1 -1
- package/dist/os/naming/naming.module.js +9 -2
- package/dist/os/naming/naming.module.js.map +1 -1
- package/dist/os/notes/notes.module.d.ts.map +1 -1
- package/dist/os/notes/notes.module.js +17 -6
- package/dist/os/notes/notes.module.js.map +1 -1
- package/dist/os/plan/plan.module.d.ts.map +1 -1
- package/dist/os/plan/plan.module.js +2 -0
- package/dist/os/plan/plan.module.js.map +1 -1
- package/dist/os/plugin/plugin.module.d.ts.map +1 -1
- package/dist/os/plugin/plugin.module.js +9 -2
- package/dist/os/plugin/plugin.module.js.map +1 -1
- package/dist/os/program/program.module.d.ts.map +1 -1
- package/dist/os/program/program.module.js +19 -4
- package/dist/os/program/program.module.js.map +1 -1
- package/dist/os/queue/handlers/queue-validate.d.ts.map +1 -1
- package/dist/os/queue/handlers/queue-validate.js +154 -7
- package/dist/os/queue/handlers/queue-validate.js.map +1 -1
- package/dist/os/queue/manifest.d.ts +17 -1
- package/dist/os/queue/manifest.d.ts.map +1 -1
- package/dist/os/queue/manifest.js +127 -6
- package/dist/os/queue/manifest.js.map +1 -1
- package/dist/os/queue/queue.module.d.ts.map +1 -1
- package/dist/os/queue/queue.module.js +32 -4
- package/dist/os/queue/queue.module.js.map +1 -1
- package/dist/os/queue/types.d.ts +100 -1
- package/dist/os/queue/types.d.ts.map +1 -1
- package/dist/os/queue/types.js +44 -0
- package/dist/os/queue/types.js.map +1 -1
- package/dist/os/rfc/handlers/implement-stamp.d.ts.map +1 -1
- package/dist/os/rfc/handlers/implement-stamp.js +28 -5
- package/dist/os/rfc/handlers/implement-stamp.js.map +1 -1
- package/dist/os/rfc/rfc.module.d.ts.map +1 -1
- package/dist/os/rfc/rfc.module.js +27 -3
- package/dist/os/rfc/rfc.module.js.map +1 -1
- package/dist/os/rfc/types.d.ts +11 -0
- package/dist/os/rfc/types.d.ts.map +1 -1
- package/dist/os/rfc/types.js +1 -0
- package/dist/os/rfc/types.js.map +1 -1
- package/dist/os/rfc/verification-evidence.d.ts +21 -0
- package/dist/os/rfc/verification-evidence.d.ts.map +1 -1
- package/dist/os/rfc/verification-evidence.js +140 -23
- package/dist/os/rfc/verification-evidence.js.map +1 -1
- package/dist/os/rfc/verification-refresh.d.ts.map +1 -1
- package/dist/os/rfc/verification-refresh.js +72 -37
- package/dist/os/rfc/verification-refresh.js.map +1 -1
- package/dist/os/session/handlers/save.d.ts.map +1 -1
- package/dist/os/session/handlers/save.js +46 -5
- package/dist/os/session/handlers/save.js.map +1 -1
- package/dist/os/session/session.module.d.ts.map +1 -1
- package/dist/os/session/session.module.js +5 -0
- package/dist/os/session/session.module.js.map +1 -1
- package/dist/os/spec/live-spec-merge.d.ts.map +1 -1
- package/dist/os/spec/live-spec-merge.js +55 -134
- package/dist/os/spec/live-spec-merge.js.map +1 -1
- package/dist/os/spec/live-spec-rebuild.d.ts +32 -0
- package/dist/os/spec/live-spec-rebuild.d.ts.map +1 -0
- package/dist/os/spec/live-spec-rebuild.js +272 -0
- package/dist/os/spec/live-spec-rebuild.js.map +1 -0
- package/dist/os/spec/live-spec-shared.d.ts +62 -0
- package/dist/os/spec/live-spec-shared.d.ts.map +1 -0
- package/dist/os/spec/live-spec-shared.js +315 -0
- package/dist/os/spec/live-spec-shared.js.map +1 -0
- package/dist/os/spec/live-spec-types.d.ts +17 -1
- package/dist/os/spec/live-spec-types.d.ts.map +1 -1
- package/dist/os/spec/live-spec-types.js +3 -0
- package/dist/os/spec/live-spec-types.js.map +1 -1
- package/dist/os/spec/live-spec-validate.d.ts.map +1 -1
- package/dist/os/spec/live-spec-validate.js +105 -2
- package/dist/os/spec/live-spec-validate.js.map +1 -1
- package/dist/os/spec/spec-materialize.d.ts +2 -0
- package/dist/os/spec/spec-materialize.d.ts.map +1 -1
- package/dist/os/spec/spec-materialize.js +45 -5
- package/dist/os/spec/spec-materialize.js.map +1 -1
- package/dist/os/spec/spec-schema.d.ts +19 -0
- package/dist/os/spec/spec-schema.d.ts.map +1 -1
- package/dist/os/spec/spec-schema.js +30 -0
- package/dist/os/spec/spec-schema.js.map +1 -1
- package/dist/os/spec/spec-status.d.ts +4 -0
- package/dist/os/spec/spec-status.d.ts.map +1 -1
- package/dist/os/spec/spec-status.js +19 -1
- package/dist/os/spec/spec-status.js.map +1 -1
- package/dist/os/spec/spec-validate.d.ts.map +1 -1
- package/dist/os/spec/spec-validate.js +55 -8
- package/dist/os/spec/spec-validate.js.map +1 -1
- package/dist/os/spec/spec.module.d.ts.map +1 -1
- package/dist/os/spec/spec.module.js +84 -8
- package/dist/os/spec/spec.module.js.map +1 -1
- package/dist/os/werkstatt/handlers/werkstatt-operation-validate.d.ts.map +1 -1
- package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js +10 -4
- package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js.map +1 -1
- package/dist/os/werkstatt/werkstatt.module.d.ts.map +1 -1
- package/dist/os/werkstatt/werkstatt.module.js +13 -4
- package/dist/os/werkstatt/werkstatt.module.js.map +1 -1
- package/dist/os/workflow/workflow.module.d.ts.map +1 -1
- package/dist/os/workflow/workflow.module.js +13 -5
- package/dist/os/workflow/workflow.module.js.map +1 -1
- package/dist/src/cli-flags.d.ts.map +1 -1
- package/dist/src/cli-flags.js +25 -5
- package/dist/src/cli-flags.js.map +1 -1
- package/dist/src/config/forge-config.d.ts +3 -0
- package/dist/src/config/forge-config.d.ts.map +1 -1
- package/dist/src/config/forge-config.js +2 -0
- package/dist/src/config/forge-config.js.map +1 -1
- package/dist/src/onboarding/init.d.ts.map +1 -1
- package/dist/src/onboarding/init.js +8 -3
- package/dist/src/onboarding/init.js.map +1 -1
- package/dist/src/pipeline-status.d.ts +14 -1
- package/dist/src/pipeline-status.d.ts.map +1 -1
- package/dist/src/pipeline-status.js +28 -8
- package/dist/src/pipeline-status.js.map +1 -1
- package/dist/src/types.d.ts +7 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +6 -0
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/generated-marker.d.ts +8 -0
- package/dist/src/utils/generated-marker.d.ts.map +1 -1
- package/dist/src/utils/generated-marker.js +25 -0
- package/dist/src/utils/generated-marker.js.map +1 -1
- package/os/adr/adr.module.ts +2 -0
- package/os/audit/audit.module.ts +2 -0
- package/os/compass/compass.module.ts +49 -15
- package/os/compass/handlers/compass-audit-handler.ts +50 -9
- package/os/compass/handlers/compass-docs-validate.ts +359 -0
- package/os/compass/handlers/summary-record.ts +104 -5
- package/os/compass/handlers/tests/compass-audit-record.test.ts +2 -1
- package/os/compass/handlers/tests/compass-audit-validate.test.ts +92 -3
- package/os/compass/handlers/tests/compass-docs-validate.test.ts +203 -0
- package/os/compass/handlers/tests/compass-ledger-scope.test.ts +2 -1
- package/os/compass/handlers/tests/summary-record.test.ts +127 -0
- package/os/core/core.module.ts +147 -75
- package/os/core/docs-archive.test.ts +136 -0
- package/os/exploration/exploration.module.ts +3 -0
- package/os/naming/naming.module.ts +9 -2
- package/os/notes/notes.module.ts +17 -6
- package/os/plan/plan-0000-template.md +150 -0
- package/os/plan/plan.module.ts +2 -0
- package/os/plugin/plugin.module.ts +9 -2
- package/os/program/program.module.ts +19 -4
- package/os/queue/decision-ledger.test.ts +163 -0
- package/os/queue/handlers/queue-validate.ts +190 -8
- package/os/queue/manifest.ts +201 -7
- package/os/queue/queue-validate.test.ts +303 -0
- package/os/queue/queue.module.ts +32 -4
- package/os/queue/types.ts +56 -1
- package/os/rfc/handlers/implement-stamp.ts +35 -5
- package/os/rfc/rfc.module.ts +29 -3
- package/os/rfc/types.ts +17 -1
- package/os/rfc/verification-emit.test.ts +305 -0
- package/os/rfc/verification-evidence.ts +155 -24
- package/os/rfc/verification-refresh.test.ts +222 -1
- package/os/rfc/verification-refresh.ts +80 -38
- package/os/session/handlers/save.ts +41 -5
- package/os/session/session.module.ts +5 -0
- package/os/spec/live-spec-idempotency.pbt.test.ts +222 -0
- package/os/spec/live-spec-list-show-validate.test.ts +10 -6
- package/os/spec/live-spec-merge.test.ts +187 -7
- package/os/spec/live-spec-merge.ts +71 -155
- package/os/spec/live-spec-rebuild.test.ts +317 -0
- package/os/spec/live-spec-rebuild.ts +356 -0
- package/os/spec/live-spec-shared.ts +378 -0
- package/os/spec/live-spec-types.ts +21 -1
- package/os/spec/live-spec-validate.test.ts +317 -0
- package/os/spec/live-spec-validate.ts +106 -2
- package/os/spec/spec-materialize.test.ts +192 -0
- package/os/spec/spec-materialize.ts +48 -4
- package/os/spec/spec-schema.ts +49 -0
- package/os/spec/spec-status.ts +24 -0
- package/os/spec/spec-validate.test.ts +66 -0
- package/os/spec/spec-validate.ts +62 -8
- package/os/spec/spec.module.ts +85 -8
- package/os/werkstatt/handlers/werkstatt-operation-validate.ts +10 -4
- package/os/werkstatt/werkstatt.module.ts +13 -4
- package/os/workflow/workflow.module.ts +13 -5
- package/package.json +1 -1
- package/skills/_shared/fo-pipeline-conventions.md +126 -1
- package/skills/fo/fo-doc-audit/SKILL.md +4 -4
- package/skills/fo/fo-explore/SKILL.md +2 -1
- package/skills/fo/fo-fix/SKILL.md +11 -3
- package/skills/fo/fo-handoff/SKILL.md +4 -6
- package/skills/fo/fo-idea-create-rfc/SKILL.md +2 -1
- package/skills/fo/fo-idea-enhance/SKILL.md +23 -4
- package/skills/fo/fo-idea-i-just-want-to-see-the-result/SKILL.md +86 -22
- package/skills/fo/fo-idea-implement/SKILL.md +53 -10
- package/skills/fo/fo-idea-plan/SKILL.md +28 -6
- package/skills/fo/fo-review/SKILL.md +69 -8
- package/skills/fo/fo-session-retro/SKILL.md +3 -2
- package/skills/fo/fo-step-commit/SKILL.md +2 -0
- package/skills/shared/grilling/SKILL.md +12 -0
- package/skills/shared/writing-great-skills/GLOSSARY.md +2 -0
- package/skills/shared/writing-great-skills/SKILL.md +2 -1
- package/src/cli-flags.ts +23 -5
- package/src/config/forge-config.ts +4 -0
- package/src/onboarding/init.ts +8 -3
- package/src/pipeline-status.ts +32 -8
- package/src/tests/cli-flags.test.ts +20 -0
- package/src/tests/cli-output.test.ts +13 -7
- package/src/tests/fixtures/agents-generate-business-before.txt +7 -7
- package/src/tests/implement-stamp.test.ts +38 -0
- package/src/tests/session-handlers.test.ts +33 -0
- package/src/types.ts +13 -1
- package/src/utils/generated-marker.ts +28 -0
- package/skills/fo/fo-idea-implement/ADR-FLOW.md +0 -179
- package/skills/fo/fo-review/AXES.md +0 -70
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { Diagnostic } from "../../src/types.ts";
|
|
2
|
-
import type { QueueManifest } from "./types.ts";
|
|
2
|
+
import type { DecisionLedger, QueueManifest } from "./types.ts";
|
|
3
3
|
export interface LoadedQueueManifest {
|
|
4
4
|
manifest: QueueManifest;
|
|
5
5
|
errors: Diagnostic[];
|
|
6
6
|
warnings: Diagnostic[];
|
|
7
|
+
/** In-queue dependsOn edges resolved from document frontmatter (RFC-1250 parking cascade). */
|
|
8
|
+
dependsOn: Map<string, string[]>;
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
11
|
* Load and validate a queue manifest. Blocking errors: unreadable/invalid
|
|
@@ -11,4 +13,18 @@ export interface LoadedQueueManifest {
|
|
|
11
13
|
* item ids, duplicates. Non-blocking: dependsOn order violations.
|
|
12
14
|
*/
|
|
13
15
|
export declare function loadQueueManifest(workspaceRoot: string, filePath: string): Promise<LoadedQueueManifest>;
|
|
16
|
+
export interface LoadedDecisionLedger {
|
|
17
|
+
ledger: DecisionLedger | null;
|
|
18
|
+
errors: Diagnostic[];
|
|
19
|
+
warnings: Diagnostic[];
|
|
20
|
+
}
|
|
21
|
+
/** Manifest `docs/queues/<id>.yaml` → sibling ledger `docs/queues/<id>.decisions.yaml`. */
|
|
22
|
+
export declare function decisionLedgerPath(manifestPath: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Load the decision ledger sibling of a queue manifest. An absent ledger is
|
|
25
|
+
* legal — it means zero recorded decisions. An unreadable or schema-invalid
|
|
26
|
+
* ledger joins the manifest load path as a QUEUE-01 blocking error: the ledger
|
|
27
|
+
* is part of the queue's durable state.
|
|
28
|
+
*/
|
|
29
|
+
export declare function loadDecisionLedger(workspaceRoot: string, filePath: string, manifest?: QueueManifest): Promise<LoadedDecisionLedger>;
|
|
14
30
|
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../os/queue/manifest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../os/queue/manifest.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,8FAA8F;IAC9F,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAClC;AAWD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,mBAAmB,CAAC,CAoJ9B;AAMD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED,2FAA2F;AAC3F,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,aAAa,GACvB,OAAO,CAAC,oBAAoB,CAAC,CAkI/B"}
|
|
@@ -2,24 +2,44 @@
|
|
|
2
2
|
<MODULE_CONTRACT>
|
|
3
3
|
<purpose>Queue manifest loading and validation (RFC-1140) — YAML parse, zod
|
|
4
4
|
schema, id↔filename stem check, item id pattern, document resolution across
|
|
5
|
-
active and archive dirs, duplicate detection, and dependsOn order warnings
|
|
5
|
+
active and archive dirs, duplicate detection, and dependsOn order warnings.
|
|
6
|
+
Also loads the decision-ledger sibling (RFC-1250).</purpose>
|
|
6
7
|
<non-goals>
|
|
7
8
|
<item>Do not derive item status — that is src/pipeline-status.ts.</item>
|
|
8
9
|
<item>Do not mutate the manifest file.</item>
|
|
9
10
|
</non-goals>
|
|
10
11
|
</MODULE_CONTRACT>
|
|
11
12
|
<CHANGE_SUMMARY>
|
|
13
|
+
<item>RFC-1250: loadDecisionLedger — sibling stem.decisions.yaml resolution,
|
|
14
|
+
ENOENT-only absence (other read errors are QUEUE-01 blocking), schema check,
|
|
15
|
+
ledger↔manifest binding (queue/id stem QUEUE-02, duplicate Q-N QUEUE-05),
|
|
16
|
+
hygiene warnings QUEUE-08 (missing answers, foreign doc ids);
|
|
17
|
+
LoadedQueueManifest exposes resolved dependsOn edges for the parking
|
|
18
|
+
cascade.</item>
|
|
12
19
|
<item>RFC-1140: initial manifest loader and validator.</item>
|
|
13
20
|
<item>RFC-1140: steps 1-4 — shared resolver, queue module, registration
|
|
14
21
|
|
|
15
22
|
Extract pipeline-status derivation into packages/forge/src/pipeline-status.ts, refactor rfc.pipeline.status onto it, add os/queue module with queue.validate command, register in WORKSHOP_MODULE_MAP.forge + bin/cli.ts + package.json exports.</item>
|
|
23
|
+
<item>RFC-1250: review wave — QUEUE-07 gates un-parked opens only, ledger binding checks, fail-closed loader
|
|
24
|
+
|
|
25
|
+
REVIEW-RFC-1250-01 findings: QUEUE-07 no longer fires on parked entries
|
|
26
|
+
(the park is the containment — a parked queue stays resumable and the
|
|
27
|
+
decision window arbitrates it); loader fails open only on ENOENT —
|
|
28
|
+
other read errors are QUEUE-01; ledger gains queue/id-stem binding
|
|
29
|
+
(QUEUE-02), Q-N uniqueness (QUEUE-05), and QUEUE-08 hygiene warnings
|
|
30
|
+
(missing answers, foreign doc ids); next excludes QUEUE-07-blocked
|
|
31
|
+
items; top-level decision totals added. Orchestrator pre-flight treats
|
|
32
|
+
QUEUE-07 as the window agenda — structural errors still stop the batch;
|
|
33
|
+
maturation skips parked/deferred items; uncovered imperative ask sites
|
|
34
|
+
gain collect riders (ADR code-trace, NC markers, audit-verdict guard).</item>
|
|
35
|
+
<item>RFC-1250: re-review wave — blocked dependsOn cascade, manifest-failure gating, generated artifacts</item>
|
|
16
36
|
</CHANGE_SUMMARY>
|
|
17
37
|
*/
|
|
18
38
|
import { ambientIo as fs } from "../../src/utils/io.js";
|
|
19
39
|
import path from "node:path";
|
|
20
40
|
import YAML from "yaml";
|
|
21
41
|
import { resolveDocument } from "../../src/pipeline-status.js";
|
|
22
|
-
import { QUEUE_ITEM_ID_PATTERN, queueManifestSchema } from "./types.js";
|
|
42
|
+
import { QUEUE_ITEM_ID_PATTERN, decisionLedgerSchema, queueManifestSchema } from "./types.js";
|
|
23
43
|
function diag(ruleId, severity, message, file) {
|
|
24
44
|
return { ruleId, severity, message, file };
|
|
25
45
|
}
|
|
@@ -39,7 +59,12 @@ export async function loadQueueManifest(workspaceRoot, filePath) {
|
|
|
39
59
|
}
|
|
40
60
|
catch (e) {
|
|
41
61
|
errors.push(diag("QUEUE-01", "error", `Cannot read queue manifest: ${e instanceof Error ? e.message : String(e)}`, displayPath));
|
|
42
|
-
return {
|
|
62
|
+
return {
|
|
63
|
+
manifest: { id: "", createdAt: "", items: [] },
|
|
64
|
+
errors,
|
|
65
|
+
warnings,
|
|
66
|
+
dependsOn: new Map(),
|
|
67
|
+
};
|
|
43
68
|
}
|
|
44
69
|
let raw;
|
|
45
70
|
try {
|
|
@@ -47,14 +72,24 @@ export async function loadQueueManifest(workspaceRoot, filePath) {
|
|
|
47
72
|
}
|
|
48
73
|
catch (e) {
|
|
49
74
|
errors.push(diag("QUEUE-01", "error", `YAML parse error: ${e instanceof Error ? e.message : String(e)}`, displayPath));
|
|
50
|
-
return {
|
|
75
|
+
return {
|
|
76
|
+
manifest: { id: "", createdAt: "", items: [] },
|
|
77
|
+
errors,
|
|
78
|
+
warnings,
|
|
79
|
+
dependsOn: new Map(),
|
|
80
|
+
};
|
|
51
81
|
}
|
|
52
82
|
const parsed = queueManifestSchema.safeParse(raw);
|
|
53
83
|
if (!parsed.success) {
|
|
54
84
|
for (const issue of parsed.error.issues) {
|
|
55
85
|
errors.push(diag("QUEUE-01", "error", `Manifest schema violation at ${issue.path.join(".") || "<root>"}: ${issue.message}`, displayPath));
|
|
56
86
|
}
|
|
57
|
-
return {
|
|
87
|
+
return {
|
|
88
|
+
manifest: { id: "", createdAt: "", items: [] },
|
|
89
|
+
errors,
|
|
90
|
+
warnings,
|
|
91
|
+
dependsOn: new Map(),
|
|
92
|
+
};
|
|
58
93
|
}
|
|
59
94
|
const manifest = parsed.data;
|
|
60
95
|
// QUEUE-02: manifest id must equal the filename stem.
|
|
@@ -101,6 +136,92 @@ export async function loadQueueManifest(workspaceRoot, filePath) {
|
|
|
101
136
|
}
|
|
102
137
|
}
|
|
103
138
|
}
|
|
104
|
-
return { manifest, errors, warnings };
|
|
139
|
+
return { manifest, errors, warnings, dependsOn: resolvedDependsOn };
|
|
140
|
+
}
|
|
141
|
+
/** Manifest `docs/queues/<id>.yaml` → sibling ledger `docs/queues/<id>.decisions.yaml`. */
|
|
142
|
+
export function decisionLedgerPath(manifestPath) {
|
|
143
|
+
return manifestPath.replace(/\.(ya?ml)$/i, ".decisions.yaml");
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Load the decision ledger sibling of a queue manifest. An absent ledger is
|
|
147
|
+
* legal — it means zero recorded decisions. An unreadable or schema-invalid
|
|
148
|
+
* ledger joins the manifest load path as a QUEUE-01 blocking error: the ledger
|
|
149
|
+
* is part of the queue's durable state.
|
|
150
|
+
*/
|
|
151
|
+
export async function loadDecisionLedger(workspaceRoot, filePath, manifest) {
|
|
152
|
+
const errors = [];
|
|
153
|
+
const warnings = [];
|
|
154
|
+
const ledgerPath = decisionLedgerPath(filePath);
|
|
155
|
+
const absolutePath = path.isAbsolute(ledgerPath)
|
|
156
|
+
? ledgerPath
|
|
157
|
+
: path.join(workspaceRoot, ledgerPath);
|
|
158
|
+
const displayPath = path.isAbsolute(ledgerPath)
|
|
159
|
+
? path.relative(workspaceRoot, ledgerPath)
|
|
160
|
+
: ledgerPath;
|
|
161
|
+
let source;
|
|
162
|
+
try {
|
|
163
|
+
source = await fs.readFile(absolutePath);
|
|
164
|
+
}
|
|
165
|
+
catch (e) {
|
|
166
|
+
// ENOENT = legal absence (zero recorded decisions). Any other read
|
|
167
|
+
// failure (EACCES, EISDIR, …) is an unreadable durable artifact — the
|
|
168
|
+
// ledger must never fail open into "no decisions" or QUEUE-07 disarms.
|
|
169
|
+
if (e.code === "ENOENT") {
|
|
170
|
+
return { ledger: null, errors, warnings };
|
|
171
|
+
}
|
|
172
|
+
errors.push(diag("QUEUE-01", "error", `Cannot read decision ledger: ${e instanceof Error ? e.message : String(e)}`, displayPath));
|
|
173
|
+
return { ledger: null, errors, warnings };
|
|
174
|
+
}
|
|
175
|
+
let raw;
|
|
176
|
+
try {
|
|
177
|
+
raw = YAML.parse(source);
|
|
178
|
+
}
|
|
179
|
+
catch (e) {
|
|
180
|
+
errors.push(diag("QUEUE-01", "error", `Decision ledger YAML parse error: ${e instanceof Error ? e.message : String(e)}`, displayPath));
|
|
181
|
+
return { ledger: null, errors, warnings };
|
|
182
|
+
}
|
|
183
|
+
const parsed = decisionLedgerSchema.safeParse(raw);
|
|
184
|
+
if (!parsed.success) {
|
|
185
|
+
for (const issue of parsed.error.issues) {
|
|
186
|
+
errors.push(diag("QUEUE-01", "error", `Decision ledger schema violation at ${issue.path.join(".") || "<root>"}: ${issue.message}`, displayPath));
|
|
187
|
+
}
|
|
188
|
+
return { ledger: null, errors, warnings };
|
|
189
|
+
}
|
|
190
|
+
const ledger = parsed.data;
|
|
191
|
+
// Binding and hygiene checks require a successfully loaded manifest — when
|
|
192
|
+
// the manifest itself failed, the stub (empty id, no items) would blame a
|
|
193
|
+
// healthy ledger for a broken queue (QUEUE-02 against "") and flag every
|
|
194
|
+
// entry as foreign (QUEUE-08). The manifest failure already blocks.
|
|
195
|
+
const manifestId = manifest?.id ?? "";
|
|
196
|
+
const manifestReady = manifestId !== "";
|
|
197
|
+
// QUEUE-02-family binding: the ledger belongs to exactly one manifest —
|
|
198
|
+
// `queue` names the manifest id and `id` names the ledger filename stem
|
|
199
|
+
// (`<manifest-stem>.decisions`). A misplaced or copy-pasted ledger must not
|
|
200
|
+
// silently apply foreign decisions to this queue.
|
|
201
|
+
const ledgerStem = path.basename(absolutePath).replace(/\.(ya?ml)$/i, "");
|
|
202
|
+
if (manifestReady && ledger.queue !== manifestId) {
|
|
203
|
+
errors.push(diag("QUEUE-02", "error", `Decision ledger queue "${ledger.queue}" does not match manifest id "${manifestId}"`, displayPath));
|
|
204
|
+
}
|
|
205
|
+
if (ledger.id !== ledgerStem) {
|
|
206
|
+
errors.push(diag("QUEUE-02", "error", `Decision ledger id "${ledger.id}" does not match filename stem "${ledgerStem}"`, displayPath));
|
|
207
|
+
}
|
|
208
|
+
// QUEUE-05-family: decision ids are queue-global — window codes and
|
|
209
|
+
// PENDING DECISION markers address them, so duplicates corrupt arbitration.
|
|
210
|
+
const seenDecisions = new Set();
|
|
211
|
+
const manifestDocs = new Set((manifest?.items ?? []).map((i) => i.id.trim().toUpperCase()));
|
|
212
|
+
for (const entry of ledger.items) {
|
|
213
|
+
if (seenDecisions.has(entry.id)) {
|
|
214
|
+
errors.push(diag("QUEUE-05", "error", `Duplicate decision id "${entry.id}"`, displayPath));
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
seenDecisions.add(entry.id);
|
|
218
|
+
if ((entry.status === "answered" || entry.status === "auto-resolved") && !entry.answer) {
|
|
219
|
+
warnings.push(diag("QUEUE-08", "warning", `Decision "${entry.id}" is ${entry.status} but carries no answer — implement has nothing to bind`, displayPath));
|
|
220
|
+
}
|
|
221
|
+
if (manifestReady && !manifestDocs.has(entry.doc.toUpperCase())) {
|
|
222
|
+
warnings.push(diag("QUEUE-08", "warning", `Decision "${entry.id}" targets "${entry.doc}" which is not a manifest item — invisible to this queue`, displayPath));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return { ledger, errors, warnings };
|
|
105
226
|
}
|
|
106
227
|
//# sourceMappingURL=manifest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../os/queue/manifest.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../os/queue/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.module.d.ts","sourceRoot":"","sources":["../../../os/queue/queue.module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"queue.module.d.ts","sourceRoot":"","sources":["../../../os/queue/queue.module.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,WAAW,CAAC,CAoDnE"}
|
|
@@ -13,6 +13,20 @@ Extract pipeline-status derivation into packages/forge/src/pipeline-status.ts, r
|
|
|
13
13
|
<item>RFC-1140: queue.validate missing contract/rules metadata (DNA-91)
|
|
14
14
|
|
|
15
15
|
fo-review REVIEW-CODE-2026-09-23-01 finding: declare contract queue and emitted ruleIds QUEUE-01..06 so validator.inventory.generate does not fail closed. Manifest regenerated.</item>
|
|
16
|
+
<item>RFC-1250: review wave — QUEUE-07 gates un-parked opens only, ledger binding checks, fail-closed loader
|
|
17
|
+
|
|
18
|
+
REVIEW-RFC-1250-01 findings: QUEUE-07 no longer fires on parked entries
|
|
19
|
+
(the park is the containment — a parked queue stays resumable and the
|
|
20
|
+
decision window arbitrates it); loader fails open only on ENOENT —
|
|
21
|
+
other read errors are QUEUE-01; ledger gains queue/id-stem binding
|
|
22
|
+
(QUEUE-02), Q-N uniqueness (QUEUE-05), and QUEUE-08 hygiene warnings
|
|
23
|
+
(missing answers, foreign doc ids); next excludes QUEUE-07-blocked
|
|
24
|
+
items; top-level decision totals added. Orchestrator pre-flight treats
|
|
25
|
+
QUEUE-07 as the window agenda — structural errors still stop the batch;
|
|
26
|
+
maturation skips parked/deferred items; uncovered imperative ask sites
|
|
27
|
+
gain collect riders (ADR code-trace, NC markers, audit-verdict guard).</item>
|
|
28
|
+
<item>RFC-1250: re-review wave — blocked dependsOn cascade, manifest-failure gating, generated artifacts</item>
|
|
29
|
+
<history>RFC-1250</history>
|
|
16
30
|
</CHANGE_SUMMARY>
|
|
17
31
|
*/
|
|
18
32
|
export async function createForgeQueueModule() {
|
|
@@ -25,12 +39,26 @@ export async function createForgeQueueModule() {
|
|
|
25
39
|
commands: [
|
|
26
40
|
{
|
|
27
41
|
name: "queue.validate",
|
|
28
|
-
description: "Validate a queue manifest (docs/queues/*.yaml) and
|
|
29
|
-
"per-item pipeline status plus the
|
|
30
|
-
"
|
|
42
|
+
description: "Validate a queue manifest (docs/queues/*.yaml) and its decision " +
|
|
43
|
+
"ledger sibling, report derived per-item pipeline status plus the " +
|
|
44
|
+
"next actionable item. QUEUE-07 blocks implementable items carrying " +
|
|
45
|
+
"un-parked open decisions (RFC-1250); QUEUE-08 warns on ledger " +
|
|
46
|
+
"hygiene issues (missing answers, foreign doc ids). Read-only — " +
|
|
47
|
+
"the pipeline orchestrator runs this before a queued batch and the " +
|
|
48
|
+
"decision window consumes its diagnostics (RFC-1140). " +
|
|
49
|
+
"Required flags: `--file`.",
|
|
31
50
|
scope: "workspace",
|
|
32
51
|
contract: "queue",
|
|
33
|
-
rules: [
|
|
52
|
+
rules: [
|
|
53
|
+
"QUEUE-01",
|
|
54
|
+
"QUEUE-02",
|
|
55
|
+
"QUEUE-03",
|
|
56
|
+
"QUEUE-04",
|
|
57
|
+
"QUEUE-05",
|
|
58
|
+
"QUEUE-06",
|
|
59
|
+
"QUEUE-07",
|
|
60
|
+
"QUEUE-08",
|
|
61
|
+
],
|
|
34
62
|
mutatesState: false,
|
|
35
63
|
reads: [
|
|
36
64
|
"docs/queues/*.yaml",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.module.js","sourceRoot":"","sources":["../../../os/queue/queue.module.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"queue.module.js","sourceRoot":"","sources":["../../../os/queue/queue.module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BE;AAIF,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;IAC1E,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,OAAO;QAChB,OAAO,EAAE,YAAY;QACrB,YAAY,EAAE,EAAE;QAChB,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,gBAAgB;gBACtB,WAAW,EACT,kEAAkE;oBAClE,mEAAmE;oBACnE,qEAAqE;oBACrE,gEAAgE;oBAChE,iEAAiE;oBACjE,oEAAoE;oBACpE,uDAAuD;oBACvD,2BAA2B;gBAC7B,KAAK,EAAE,WAAW;gBAClB,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE;oBACL,UAAU;oBACV,UAAU;oBACV,UAAU;oBACV,UAAU;oBACV,UAAU;oBACV,UAAU;oBACV,UAAU;oBACV,UAAU;iBACX;gBACD,YAAY,EAAE,KAAK;gBACnB,KAAK,EAAE;oBACL,oBAAoB;oBACpB,mBAAmB;oBACnB,mBAAmB;oBACnB,kBAAkB;oBAClB,iBAAiB;iBAClB;gBACD,SAAS,EAAE,KAAK;gBAChB,KAAK,EAAE;oBACL,IAAI,EAAE;wBACJ,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,IAAI;wBACd,WAAW,EAAE,uCAAuC;qBACrD;iBACF;gBACD,OAAO,EAAE,gBAAgB;aAC1B;SACF;QACD,SAAS,EAAE,EAAE;KACd,CAAC;AACJ,CAAC"}
|
package/dist/os/queue/types.d.ts
CHANGED
|
@@ -2,6 +2,98 @@ import { z } from "zod";
|
|
|
2
2
|
import type { Diagnostic } from "../../src/types.ts";
|
|
3
3
|
import type { QueueItemReport } from "../../src/pipeline-status.ts";
|
|
4
4
|
export declare const QUEUE_ITEM_ID_PATTERN: RegExp;
|
|
5
|
+
export declare const DECISION_STATUS: readonly ["open", "answered", "auto-resolved", "deferred"];
|
|
6
|
+
export type DecisionStatus = (typeof DECISION_STATUS)[number];
|
|
7
|
+
export declare const decisionOptionSchema: z.ZodObject<{
|
|
8
|
+
label: z.ZodString;
|
|
9
|
+
consequence: z.ZodOptional<z.ZodString>;
|
|
10
|
+
recommended: z.ZodOptional<z.ZodBoolean>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export declare const decisionEntrySchema: z.ZodObject<{
|
|
13
|
+
id: z.ZodString;
|
|
14
|
+
doc: z.ZodString;
|
|
15
|
+
stage: z.ZodEnum<{
|
|
16
|
+
plan: "plan";
|
|
17
|
+
review: "review";
|
|
18
|
+
enhance: "enhance";
|
|
19
|
+
implement: "implement";
|
|
20
|
+
idea: "idea";
|
|
21
|
+
}>;
|
|
22
|
+
question: z.ZodString;
|
|
23
|
+
resolutionPath: z.ZodEnum<{
|
|
24
|
+
none: "none";
|
|
25
|
+
profile: "profile";
|
|
26
|
+
policy: "policy";
|
|
27
|
+
codebase: "codebase";
|
|
28
|
+
convention: "convention";
|
|
29
|
+
}>;
|
|
30
|
+
options: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
31
|
+
label: z.ZodString;
|
|
32
|
+
consequence: z.ZodOptional<z.ZodString>;
|
|
33
|
+
recommended: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
}, z.core.$strip>>>;
|
|
35
|
+
status: z.ZodDefault<z.ZodEnum<{
|
|
36
|
+
open: "open";
|
|
37
|
+
answered: "answered";
|
|
38
|
+
"auto-resolved": "auto-resolved";
|
|
39
|
+
deferred: "deferred";
|
|
40
|
+
}>>;
|
|
41
|
+
answer: z.ZodOptional<z.ZodString>;
|
|
42
|
+
answeredAt: z.ZodOptional<z.ZodString>;
|
|
43
|
+
parked: z.ZodOptional<z.ZodBoolean>;
|
|
44
|
+
}, z.core.$strip>;
|
|
45
|
+
export declare const decisionPolicySchema: z.ZodObject<{
|
|
46
|
+
id: z.ZodString;
|
|
47
|
+
question: z.ZodString;
|
|
48
|
+
answer: z.ZodString;
|
|
49
|
+
appliesTo: z.ZodUnion<readonly [z.ZodLiteral<"*">, z.ZodArray<z.ZodString>]>;
|
|
50
|
+
}, z.core.$strip>;
|
|
51
|
+
export declare const decisionLedgerSchema: z.ZodObject<{
|
|
52
|
+
id: z.ZodString;
|
|
53
|
+
queue: z.ZodString;
|
|
54
|
+
createdAt: z.ZodString;
|
|
55
|
+
policies: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
56
|
+
id: z.ZodString;
|
|
57
|
+
question: z.ZodString;
|
|
58
|
+
answer: z.ZodString;
|
|
59
|
+
appliesTo: z.ZodUnion<readonly [z.ZodLiteral<"*">, z.ZodArray<z.ZodString>]>;
|
|
60
|
+
}, z.core.$strip>>>;
|
|
61
|
+
items: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
62
|
+
id: z.ZodString;
|
|
63
|
+
doc: z.ZodString;
|
|
64
|
+
stage: z.ZodEnum<{
|
|
65
|
+
plan: "plan";
|
|
66
|
+
review: "review";
|
|
67
|
+
enhance: "enhance";
|
|
68
|
+
implement: "implement";
|
|
69
|
+
idea: "idea";
|
|
70
|
+
}>;
|
|
71
|
+
question: z.ZodString;
|
|
72
|
+
resolutionPath: z.ZodEnum<{
|
|
73
|
+
none: "none";
|
|
74
|
+
profile: "profile";
|
|
75
|
+
policy: "policy";
|
|
76
|
+
codebase: "codebase";
|
|
77
|
+
convention: "convention";
|
|
78
|
+
}>;
|
|
79
|
+
options: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
80
|
+
label: z.ZodString;
|
|
81
|
+
consequence: z.ZodOptional<z.ZodString>;
|
|
82
|
+
recommended: z.ZodOptional<z.ZodBoolean>;
|
|
83
|
+
}, z.core.$strip>>>;
|
|
84
|
+
status: z.ZodDefault<z.ZodEnum<{
|
|
85
|
+
open: "open";
|
|
86
|
+
answered: "answered";
|
|
87
|
+
"auto-resolved": "auto-resolved";
|
|
88
|
+
deferred: "deferred";
|
|
89
|
+
}>>;
|
|
90
|
+
answer: z.ZodOptional<z.ZodString>;
|
|
91
|
+
answeredAt: z.ZodOptional<z.ZodString>;
|
|
92
|
+
parked: z.ZodOptional<z.ZodBoolean>;
|
|
93
|
+
}, z.core.$strip>>>;
|
|
94
|
+
}, z.core.$strip>;
|
|
95
|
+
export type DecisionEntry = z.infer<typeof decisionEntrySchema>;
|
|
96
|
+
export type DecisionLedger = z.infer<typeof decisionLedgerSchema>;
|
|
5
97
|
export declare const queueManifestSchema: z.ZodObject<{
|
|
6
98
|
id: z.ZodString;
|
|
7
99
|
createdAt: z.ZodString;
|
|
@@ -17,8 +109,15 @@ export interface QueueValidateResult {
|
|
|
17
109
|
queue: string;
|
|
18
110
|
file: string;
|
|
19
111
|
items: QueueItemReport[];
|
|
20
|
-
/** First item
|
|
112
|
+
/** First actionable item — pending/in-progress, not parked or QUEUE-07-blocked; null when none. */
|
|
21
113
|
next: string | null;
|
|
114
|
+
/** Aggregate decision counts across the ledger (present when a sibling ledger exists). */
|
|
115
|
+
decisions?: {
|
|
116
|
+
open: number;
|
|
117
|
+
answered: number;
|
|
118
|
+
deferred: number;
|
|
119
|
+
autoResolved: number;
|
|
120
|
+
};
|
|
22
121
|
errors: Diagnostic[];
|
|
23
122
|
warnings: Diagnostic[];
|
|
24
123
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../os/queue/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../os/queue/types.ts"],"names":[],"mappings":"AA6BA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,qBAAqB,QAAsB,CAAC;AAEzD,eAAO,MAAM,eAAe,4DAA6D,CAAC;AAC1F,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,eAAO,MAAM,oBAAoB;;;;iBAI/B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAW9B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;iBAK/B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAM/B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,mBAAmB;;;;;;;iBAW9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,mGAAmG;IACnG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,0FAA0F;IAC1F,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IACvF,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB"}
|
package/dist/os/queue/types.js
CHANGED
|
@@ -7,14 +7,58 @@ block consumed by queue.validate and the pipeline orchestrator's queue mode.</pu
|
|
|
7
7
|
</non-goals>
|
|
8
8
|
</MODULE_CONTRACT>
|
|
9
9
|
<CHANGE_SUMMARY>
|
|
10
|
+
<item>RFC-1250: decision-ledger schemas — DecisionLedger, DecisionEntry, DecisionStatus, policies.</item>
|
|
10
11
|
<item>RFC-1140: initial QueueManifest schema and queue.validate result types.</item>
|
|
11
12
|
<item>RFC-1140: steps 1-4 — shared resolver, queue module, registration
|
|
12
13
|
|
|
13
14
|
Extract pipeline-status derivation into packages/forge/src/pipeline-status.ts, refactor rfc.pipeline.status onto it, add os/queue module with queue.validate command, register in WORKSHOP_MODULE_MAP.forge + bin/cli.ts + package.json exports.</item>
|
|
15
|
+
<item>RFC-1250: review wave — QUEUE-07 gates un-parked opens only, ledger binding checks, fail-closed loader
|
|
16
|
+
|
|
17
|
+
REVIEW-RFC-1250-01 findings: QUEUE-07 no longer fires on parked entries
|
|
18
|
+
(the park is the containment — a parked queue stays resumable and the
|
|
19
|
+
decision window arbitrates it); loader fails open only on ENOENT —
|
|
20
|
+
other read errors are QUEUE-01; ledger gains queue/id-stem binding
|
|
21
|
+
(QUEUE-02), Q-N uniqueness (QUEUE-05), and QUEUE-08 hygiene warnings
|
|
22
|
+
(missing answers, foreign doc ids); next excludes QUEUE-07-blocked
|
|
23
|
+
items; top-level decision totals added. Orchestrator pre-flight treats
|
|
24
|
+
QUEUE-07 as the window agenda — structural errors still stop the batch;
|
|
25
|
+
maturation skips parked/deferred items; uncovered imperative ask sites
|
|
26
|
+
gain collect riders (ADR code-trace, NC markers, audit-verdict guard).</item>
|
|
14
27
|
</CHANGE_SUMMARY>
|
|
15
28
|
*/
|
|
16
29
|
import { z } from "zod";
|
|
17
30
|
export const QUEUE_ITEM_ID_PATTERN = /^(RFC|ADR)-\d{4}$/;
|
|
31
|
+
export const DECISION_STATUS = ["open", "answered", "auto-resolved", "deferred"];
|
|
32
|
+
export const decisionOptionSchema = z.object({
|
|
33
|
+
label: z.string().min(1),
|
|
34
|
+
consequence: z.string().optional(),
|
|
35
|
+
recommended: z.boolean().optional(),
|
|
36
|
+
});
|
|
37
|
+
export const decisionEntrySchema = z.object({
|
|
38
|
+
id: z.string().regex(/^Q-\d+$/),
|
|
39
|
+
doc: z.string().regex(QUEUE_ITEM_ID_PATTERN),
|
|
40
|
+
stage: z.enum(["idea", "enhance", "plan", "implement", "review"]),
|
|
41
|
+
question: z.string().min(1),
|
|
42
|
+
resolutionPath: z.enum(["codebase", "convention", "profile", "policy", "none"]),
|
|
43
|
+
options: z.array(decisionOptionSchema).default([]),
|
|
44
|
+
status: z.enum(DECISION_STATUS).default("open"),
|
|
45
|
+
answer: z.string().optional(),
|
|
46
|
+
answeredAt: z.string().optional(),
|
|
47
|
+
parked: z.boolean().optional(),
|
|
48
|
+
});
|
|
49
|
+
export const decisionPolicySchema = z.object({
|
|
50
|
+
id: z.string().min(1),
|
|
51
|
+
question: z.string().min(1),
|
|
52
|
+
answer: z.string().min(1),
|
|
53
|
+
appliesTo: z.union([z.literal("*"), z.array(z.string())]),
|
|
54
|
+
});
|
|
55
|
+
export const decisionLedgerSchema = z.object({
|
|
56
|
+
id: z.string().min(1),
|
|
57
|
+
queue: z.string().min(1),
|
|
58
|
+
createdAt: z.string().min(1),
|
|
59
|
+
policies: z.array(decisionPolicySchema).default([]),
|
|
60
|
+
items: z.array(decisionEntrySchema).default([]),
|
|
61
|
+
});
|
|
18
62
|
export const queueManifestSchema = z.object({
|
|
19
63
|
id: z.string().min(1),
|
|
20
64
|
createdAt: z.string().min(1),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../os/queue/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../os/queue/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implement-stamp.d.ts","sourceRoot":"","sources":["../../../../os/rfc/handlers/implement-stamp.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"implement-stamp.d.ts","sourceRoot":"","sources":["../../../../os/rfc/handlers/implement-stamp.ts"],"names":[],"mappings":"AA8CA,OAAO,KAAK,EAAyC,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAKlG,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAgM/B,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,uBAAuB,CAAC,CAAC,CA2TtD"}
|
|
@@ -21,6 +21,7 @@ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten
|
|
|
21
21
|
<item>RFC-1097: sweep — packages/forge + services clean
|
|
22
22
|
|
|
23
23
|
Sweep batch 2: real KEY_DECISIONS on 10 files, expanded purposes (CONTRACT-02/PURPOSE-02), headers on mission/index + gen-upstreams, sanitizeItemText in summary.record (literal Compass tags corrupted history), excludedPaths for wrangler types, test-fixtures testPattern. forge+services now 0 diagnostics under --mode error.</item>
|
|
24
|
+
<item>Session-retro 2026-10-08: auto-detect picks the sole implement/feat-prefixed candidate among multi-commit references (RFC-IMP-03 no longer blocks full pipelines); ambiguous sets keep blocking with annotated candidate list + earliest-candidate suggestion.</item>
|
|
24
25
|
<history>RFC-0268, RFC-0476, RFC-0756</history>
|
|
25
26
|
</CHANGE_SUMMARY>
|
|
26
27
|
*/
|
|
@@ -39,6 +40,10 @@ import { RFC_DIR, RFC_METADATA_CUTOFF, RFC_PROBE_BINDING_CUTOFF } from "../types
|
|
|
39
40
|
const io = ambientIo;
|
|
40
41
|
const VERIFICATION_DIR = join(RFC_DIR, "verification");
|
|
41
42
|
// ─── Git helpers ─────────────────────────────────────────────────────────────
|
|
43
|
+
// Pipeline convention: the implementation commit's subject carries an
|
|
44
|
+
// `implement:` (or `feat:`) conventional prefix — audit/enhance/plan/docs/
|
|
45
|
+
// review/fix/chore commits referencing the same RFC id never claim it.
|
|
46
|
+
const IMPLEMENTATION_SUBJECT_RE = /^(implement|feat)(\([^)]*\))?!?:/i;
|
|
42
47
|
function execGit(workspaceRoot, args) {
|
|
43
48
|
return new Promise((resolve) => {
|
|
44
49
|
execFile("git", args, { cwd: workspaceRoot, timeout: 10000 }, (err, stdout) => {
|
|
@@ -268,11 +273,29 @@ export async function runRfcImplementStamp(input, context) {
|
|
|
268
273
|
});
|
|
269
274
|
}
|
|
270
275
|
else {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
+
// Auto-resolve when exactly one candidate looks like an implementation
|
|
277
|
+
// commit — a multi-commit RFC pipeline (audit → plan → implement → docs →
|
|
278
|
+
// review) references the id at every step, but only one step implements.
|
|
279
|
+
const implCandidates = detected.multiple.filter((c) => IMPLEMENTATION_SUBJECT_RE.test(c.message));
|
|
280
|
+
if (implCandidates.length === 1) {
|
|
281
|
+
implementationCommit = implCandidates[0].sha;
|
|
282
|
+
logger.info(`[rfc.implement.stamp] auto-selected implementation commit ${implCandidates[0].sha} (sole implement/feat-prefixed candidate)`);
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
const candidateList = detected.multiple
|
|
286
|
+
.map((c) => ` ${c.sha} — ${c.message}${IMPLEMENTATION_SUBJECT_RE.test(c.message) ? " [implementation-shaped]" : ""}`)
|
|
287
|
+
.join("\n");
|
|
288
|
+
// git log lists newest first — the earliest implementation-shaped
|
|
289
|
+
// commit is the most likely canonical pick for a step-wise wave.
|
|
290
|
+
const earliest = implCandidates[implCandidates.length - 1];
|
|
291
|
+
const suggestion = earliest
|
|
292
|
+
? `\nLikely: ${earliest.sha} (earliest implementation-shaped commit).`
|
|
293
|
+
: "";
|
|
294
|
+
violations.push({
|
|
295
|
+
rule: "RFC-IMP-03",
|
|
296
|
+
message: `Multiple commits reference ${targetId}:\n${candidateList}\nPass --implementation-commit <SHA> to specify which one.${suggestion}`,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
276
299
|
}
|
|
277
300
|
}
|
|
278
301
|
// ── RFC-IMP-04: RFC file must be clean (no uncommitted edits to the target RFC) ──
|