Initial publish v0.1.0: standalone workflow core (corpus + examples + guards)
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"namespace": "https://eightarms.net/octopus-workflow/schemas/",
|
||||
"frozen": false,
|
||||
"note": "发布仓创建时置 frozen: true——$id 一经发布不可变(v3 §G);别名保留 ≥2 个 major 版本",
|
||||
"aliases": [
|
||||
{
|
||||
"old": "https://eightarms.net/fourbroad/octopus/.octopus/schemas/port-analysis.schema.json",
|
||||
"new": "https://eightarms.net/octopus-workflow/schemas/port-analysis.schema.json"
|
||||
},
|
||||
{
|
||||
"old": "https://eightarms.net/fourbroad/octopus/.octopus/schemas/review-status.schema.json",
|
||||
"new": "https://eightarms.net/octopus-workflow/schemas/review-status.schema.json"
|
||||
},
|
||||
{
|
||||
"old": "https://eightarms.net/fourbroad/octopus/.octopus/schemas/reviewer-output.schema.json",
|
||||
"new": "https://eightarms.net/octopus-workflow/schemas/reviewer-output.schema.json"
|
||||
},
|
||||
{
|
||||
"old": "https://eightarms.net/fourbroad/octopus/.octopus/schemas/runs-bundle.schema.json",
|
||||
"new": "https://eightarms.net/octopus-workflow/schemas/runs-bundle.schema.json"
|
||||
},
|
||||
{
|
||||
"old": "https://eightarms.net/fourbroad/octopus/.octopus/schemas/runs-index.schema.json",
|
||||
"new": "https://eightarms.net/octopus-workflow/schemas/runs-index.schema.json"
|
||||
},
|
||||
{
|
||||
"old": "https://eightarms.net/fourbroad/octopus/.octopus/schemas/runs-meta.schema.json",
|
||||
"new": "https://eightarms.net/octopus-workflow/schemas/runs-meta.schema.json"
|
||||
},
|
||||
{
|
||||
"old": "https://eightarms.net/fourbroad/octopus/.octopus/schemas/synthesis.schema.json",
|
||||
"new": "https://eightarms.net/octopus-workflow/schemas/synthesis.schema.json"
|
||||
},
|
||||
{
|
||||
"old": "https://eightarms.net/fourbroad/octopus/.octopus/schemas/workflow-routing.schema.json",
|
||||
"new": "https://eightarms.net/octopus-workflow/schemas/workflow-routing.schema.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://eightarms.net/octopus-workflow/schemas/port-analysis.schema.json",
|
||||
"title": "Port Analysis Reviewer Output",
|
||||
"description": "Schema for per-dimension port-analysis reviewer findings. Used by the large-port-pipeline source analysis review (Phase B1.5). The port source-analysis pipeline uses a deliberate three-value severity contract 鈥?BLOCKER / MAJOR / MINOR 鈥?and never emits INFO (matching implement/reference/large-port-pipeline.md and source-analysis.md, which name only those three). This is a documented exception to the canonical four-value set (BLOCKER / MAJOR / MINOR / INFO) in reviewer-output.schema.json and synthesis.schema.json.",
|
||||
"type": "object",
|
||||
"required": ["dimension", "findings"],
|
||||
"properties": {
|
||||
"dimension": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"SRC-CMP",
|
||||
"SRC-API",
|
||||
"SRC-DATA",
|
||||
"SRC-BIZ",
|
||||
"SRC-ERR",
|
||||
"SRC-DEP",
|
||||
"SRC-TST",
|
||||
"SRC-MAP",
|
||||
"TGT-SURF",
|
||||
"CAP-BOUND"
|
||||
],
|
||||
"description": "Audit dimension code"
|
||||
},
|
||||
"findings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["id", "severity", "description"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^(SRC-CMP|SRC-API|SRC-DATA|SRC-BIZ|SRC-ERR|SRC-DEP|SRC-TST|SRC-MAP|TGT-SURF|CAP-BOUND)-\\d{3}$",
|
||||
"description": "Finding ID in {DIM_CODE}-{NNN} format"
|
||||
},
|
||||
"severity": {
|
||||
"type": "string",
|
||||
"enum": ["BLOCKER", "MAJOR", "MINOR"]
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Human-readable finding description"
|
||||
},
|
||||
"source_evidence": {
|
||||
"type": "string",
|
||||
"description": "Source file:line reference citing the evidence"
|
||||
},
|
||||
"recommendation": {
|
||||
"type": "string",
|
||||
"description": "Concrete fix suggestion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://eightarms.net/octopus-workflow/schemas/review-status.schema.json",
|
||||
"title": "Review Status",
|
||||
"description": "Schema for tracking the lifecycle state of a review session. This file lives at runs/{slug}/reviews/{stage}/status.json: initialized by the Orchestrator at Phase A (step 0.5) with the full required set, appended by the Synthesizer at Phase B (history[] + current_round), and finalized with `converged` by the Orchestrator at Phase E (see skills/_shared/review-pipeline-phases.md). Reader: the retrospective token-telemetry probe (retrospective/scripts/token-telemetry.ts) walks runs/**/reviews/*/status.json (canonical) and the legacy .artifacts/**/reviews/*/status.json, reading `history[]` (code-level legacy alias `rounds[]`, both handled) and `current_round`. For CLOSED runs (active workspace removed at archive-at-close), the probe reconstructs per-stage round counts from reviews/{stage}/round{N}/ artifact paths in the committed archive bundle runs/archive/{slug}.json ([org-internal #2591]). Since TD/TRC-F006 ([org-internal #2688]) the archive bundle can also embed an explicit digest of this history[] (top-level review_history: {stage, rounds, final_verdict, per_round[]}) so round counts and verdicts stay verifiable offline, without path reconstruction.",
|
||||
"type": "object",
|
||||
"required": ["slug", "started_at", "current_round", "max_rounds", "converged", "history"],
|
||||
"properties": {
|
||||
"slug": {
|
||||
"type": "string"
|
||||
},
|
||||
"started_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"current_round": {
|
||||
"type": "integer"
|
||||
},
|
||||
"max_rounds": {
|
||||
"type": "integer",
|
||||
"default": 3,
|
||||
"description": "Per-skill bound: `review-artifact` skill (process target) = 3 (the roadmap/design/plan targets were archived 2026-08-21, [org-internal #3072] phase 3); `review-code` = 2 default / 3 high-risk (`workflow-routing.yaml` `review.max_rounds`, [org-internal #3567]). `review-dag` (the review-artifact skill's DAG single-gate target) binds per depth from `dag_metrics.review_depth`: D1 鈮?, D2 鈮?, D3 鈮?, D4 鈮? 鈥?D4 reaches round 4, exceeding the shared `review-artifact` default, so the DAG per-depth cap takes precedence (see review-artifact/SKILL.md review-dag Phase D MAX_ROUNDS). Set explicitly by the skill; default 3 is a fallback only."
|
||||
},
|
||||
"converged": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"history": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["round", "overall_verdict", "blockers", "majors"],
|
||||
"properties": {
|
||||
"round": {
|
||||
"type": "integer"
|
||||
},
|
||||
"overall_verdict": {
|
||||
"type": "string",
|
||||
"enum": ["PASS", "WARN", "FAIL"]
|
||||
},
|
||||
"blockers": {
|
||||
"type": "integer"
|
||||
},
|
||||
"majors": {
|
||||
"type": "integer"
|
||||
},
|
||||
"minors": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Count of MINOR findings for this round"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://eightarms.net/octopus-workflow/schemas/reviewer-output.schema.json",
|
||||
"title": "Reviewer Output",
|
||||
"description": "Schema for a single reviewer's output for one review dimension. Also the Tier 1 review-findings schema ([org-internal #1988]): migrated skills (review-code) write each dimension's finding as a JSON file at runs/{slug}/reviews/{stage}/round{N}/findings-{DIMENSION_CODE}.json validated by this schema; the index.json row for that file carries type=review-findings, schema=this $id. When a dimension has multiple reviewers (dim_split > 1, e.g. D3 TOPO:2 / D4 TOPO:2), each writes its OWN slot file findings-{DIMENSION_CODE}-r{k}.json with reviewer_slot/reviewer_count set. See templates/runs-layout.md and rules/two-tier-artifacts.md.",
|
||||
"type": "object",
|
||||
"required": ["dimension", "dimension_label", "verdict", "quantitative_summary", "findings", "reviewed_files"],
|
||||
"properties": {
|
||||
"dimension": {
|
||||
"type": "string",
|
||||
"description": "Dimension code (e.g. COR, SEC, PERF, TRC)"
|
||||
},
|
||||
"dimension_label": {
|
||||
"type": "string",
|
||||
"description": "Human-readable label"
|
||||
},
|
||||
"reviewer_slot": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "1-based slot of this reviewer WITHIN its dimension, when dim_split assigns >1 reviewer to the dimension (e.g. review-dag D3 TOPO:2, D4 TOPO:2 鈥?dim_split per `workflow-routing.yaml` dag.size_derivation.review_depth). Multi-reviewer dimensions write one file per slot: findings-{DIMENSION_CODE}-r{k}.json. Omitted for single-reviewer dimensions (file stays findings-{DIMENSION_CODE}.json). Preserves per-reviewer attribution for the retrospective overlap analysis ([org-internal #2996] step 1a)."
|
||||
},
|
||||
"reviewer_count": {
|
||||
"type": "integer",
|
||||
"minimum": 2,
|
||||
"description": "Total reviewers assigned to this dimension in this round (set together with reviewer_slot)."
|
||||
},
|
||||
"verdict": {
|
||||
"type": "string",
|
||||
"enum": ["PASS", "WARN", "FAIL", "UNRESOLVED"],
|
||||
"description": "PASS: pass_rate = 1.0 (no failed checks). WARN: pass_rate >= 0.7 and no BLOCKER findings. FAIL: any BLOCKER finding OR pass_rate < 0.7."
|
||||
},
|
||||
"quantitative_summary": {
|
||||
"type": "object",
|
||||
"required": ["total_checks", "passed", "failed", "pass_rate"],
|
||||
"properties": {
|
||||
"total_checks": { "type": "integer", "minimum": 1 },
|
||||
"passed": { "type": "integer", "minimum": 0 },
|
||||
"failed": { "type": "integer", "minimum": 0 },
|
||||
"pass_rate": { "type": "number", "minimum": 0, "maximum": 1 },
|
||||
"na_count": { "type": "integer", "minimum": 0, "description": "Count of not-applicable items" },
|
||||
"blocker_count": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Count of BLOCKER findings (consumed by synthesis_task.md aggregation)"
|
||||
},
|
||||
"major_count": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Count of MAJOR findings (consumed by synthesis_task.md aggregation)"
|
||||
},
|
||||
"minor_count": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Count of MINOR findings (consumed by synthesis_task.md aggregation)"
|
||||
},
|
||||
"info_count": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Count of INFO findings (consumed by synthesis_task.md aggregation)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"findings": {
|
||||
"type": "array",
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["id", "severity", "checklist_ref", "location", "summary", "detail", "evidence", "suggestion"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z0-9]+-F\\d{3,}$",
|
||||
"description": "Unique finding ID within the dimension file, form {OWN_DIMENSION_CODE}-F{NNN}, e.g. COR-F001. In a grouped dispatch the id uses the finding's OWN dimension code (e.g. TST-F001 inside the COR+TST+DBT group), never the joined group code. NOTE: uniqueness of the id VALUE is NOT enforced by findings[] uniqueItems (JSON Schema uniqueItems compares whole objects by deep equality); the synthesizer MUST post-check that id values are unique across all findings-{DIM}*.json files of the round (wired as step 1b of _shared/synthesis_task.md). Multi-slot dimensions (reviewer_slot set): prefix the slot in the id, e.g. TOPOR1-F001 / TOPOR2-F001, so ids stay unique across a dimension's slot files while still matching this pattern."
|
||||
},
|
||||
"severity": {
|
||||
"type": "string",
|
||||
"enum": ["BLOCKER", "MAJOR", "MINOR", "INFO"]
|
||||
},
|
||||
"checklist_ref": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z0-9]{2,6} \\d+(\\.\\d+)+(\\s*\\([^\\)]*\\))?(\\s*/\\s*[A-Z0-9]{2,6} \\d+(\\.\\d+)+(\\s*\\([^\\)]*\\))?)*$",
|
||||
"description": "Checklist item reference, e.g. COR 1.1, INV 1.3, SEC 3.7.1, STD 8.4 鈥?dimension/section code followed by item number(s)."
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"description": "File:line or file:section where the issue occurs"
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"description": "One-line description"
|
||||
},
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"description": "Full explanation of the finding"
|
||||
},
|
||||
"evidence": {
|
||||
"type": "string",
|
||||
"description": "Quote or excerpt from the document that supports this finding"
|
||||
},
|
||||
"suggestion": {
|
||||
"type": "string",
|
||||
"description": "Actionable recommendation to resolve the finding"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"reviewed_files": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "List of files actually reviewed"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://eightarms.net/octopus-workflow/schemas/runs-bundle.schema.json",
|
||||
"title": "Tier 1 Run Archive Bundle",
|
||||
"description": "Composite archive bundle committed at close: runs/archive/{slug}.json = {meta, index}. Dual-profile by schema_version: >= 2 strict (closed core field set + free-form context bag), 1 or absent legacy (structural typing only; historical drift normalized by repair-run-bundles.ts, see [org-internal #2588]). Validated by validate-run-bundles.ts; CI wiring: .gitea/workflows/octopus-schemas.yml. Authoritative layout: templates/runs-layout.md. Boundary rule: rules/two-tier-artifacts.md.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["meta", "index"],
|
||||
"properties": {
|
||||
"meta": true,
|
||||
"index": true,
|
||||
"working_notes": {
|
||||
"type": "string",
|
||||
"description": "Final content of runs/{slug}/working-notes.md ([org-internal #2600]), inlined at archive time when the file exists. The one Tier 1 artifact whose CONTENT (not just digest) rides in the bundle 鈥?the run's narrative memory (decisions, dead ends, reviewer feedback), consumed by later retro probes and the notes-injection degradation path ([org-internal #2601]). Absent when the run kept no working notes."
|
||||
},
|
||||
"review_history": {
|
||||
"type": "array",
|
||||
"description": "Offline-verifiability digest of the run's review rounds (TD/TRC-F006, [org-internal #2688]): one entry per review stage the run executed, each derived from that stage's live reviews/{stage}/status.json history[] at archive time. Lets closed-run probes reconstruct round counts and verdicts from the bundle alone, without the (removed) live workspace or path reconstruction ([org-internal #2591]). Absent when the run kept no review rounds.",
|
||||
"items": { "$ref": "#/$defs/reviewHistoryEntry" }
|
||||
}
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"meta": {
|
||||
"properties": { "schema_version": { "const": 2 } },
|
||||
"required": ["schema_version"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": { "properties": { "meta": { "$ref": "#/$defs/metaStrict" } } },
|
||||
"else": { "properties": { "meta": { "$ref": "#/$defs/metaLegacy" } } }
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"index": {
|
||||
"properties": { "schema_version": { "const": 2 } },
|
||||
"required": ["schema_version"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": { "properties": { "index": { "$ref": "#/$defs/indexStrict" } } },
|
||||
"else": { "properties": { "index": { "$ref": "#/$defs/indexLegacy" } } }
|
||||
}
|
||||
],
|
||||
"$defs": {
|
||||
"reviewHistoryEntry": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["stage", "rounds", "final_verdict"],
|
||||
"description": "Per-stage summary of one review stage's rounds. Shapes mirror review-status.schema.json (stage dir name; history[] item fields).",
|
||||
"properties": {
|
||||
"stage": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Review stage identifier matching the reviews/{stage}/ directory (e.g. code, review-dag, audit-process 鈥?the live values; design-space is a retired historical value)."
|
||||
},
|
||||
"rounds": { "type": "integer", "minimum": 1, "description": "Number of executed rounds." },
|
||||
"final_verdict": { "type": "string", "enum": ["PASS", "WARN", "FAIL"] },
|
||||
"per_round": {
|
||||
"type": "array",
|
||||
"description": "One entry per executed round, mirroring the live status.json history[] items.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["round", "overall_verdict", "blockers", "majors"],
|
||||
"properties": {
|
||||
"round": { "type": "integer", "minimum": 1 },
|
||||
"overall_verdict": { "type": "string", "enum": ["PASS", "WARN", "FAIL"] },
|
||||
"blockers": { "type": "integer", "minimum": 0 },
|
||||
"majors": { "type": "integer", "minimum": 0 },
|
||||
"minors": { "type": "integer", "minimum": 0, "description": "Count of MINOR findings for this round." }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ticket": {
|
||||
"oneOf": [
|
||||
{ "type": "null" },
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["owner", "repo", "number"],
|
||||
"properties": {
|
||||
"owner": { "type": "string", "minLength": 1 },
|
||||
"repo": { "type": "string", "minLength": 1 },
|
||||
"number": { "type": "integer", "minimum": 1 }
|
||||
}
|
||||
}
|
||||
],
|
||||
"description": "Source issue reference, or null for an ad-hoc run (no ticket)."
|
||||
},
|
||||
"parentEpic": {
|
||||
"oneOf": [
|
||||
{ "type": "null" },
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["number"],
|
||||
"properties": { "number": { "type": "integer", "minimum": 1 } }
|
||||
}
|
||||
],
|
||||
"description": "Parent Epic issue number, or null if the run is not under an Epic."
|
||||
},
|
||||
"metaLegacy": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["slug", "state", "created_at"],
|
||||
"description": "Legacy profile (schema_version 1 or absent): historical bundles AND current live-workspace runs 鈥?runs-meta.schema.json / runs-index.schema.json pin schema_version 1 today. Core fields type-checked when present; extra context properties (route/pr/node/kind/...) tolerated as-is. The v2 strict profile (below) is the migration target: it becomes the profile for new runs once the live-workspace schemas are bumped to emit schema_version 2 with the context bag.",
|
||||
"properties": {
|
||||
"schema_version": { "type": "integer", "minimum": 1 },
|
||||
"slug": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
||||
"branch": { "type": "string" },
|
||||
"state": { "type": "string", "enum": ["active", "archived"] },
|
||||
"created_at": { "type": "string", "anyOf": [{ "format": "date-time" }, { "format": "date" }] },
|
||||
"updated_at": { "type": "string", "anyOf": [{ "format": "date-time" }, { "format": "date" }] },
|
||||
"closed_at": { "type": ["string", "null"], "anyOf": [{ "format": "date-time" }, { "format": "date" }] },
|
||||
"close_commit_sha": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^([0-9a-f]{40}|[0-9a-f]{64})$",
|
||||
"description": "Full git SHA, or null when unresolvable (legacy runs whose landing commit is unknown)."
|
||||
},
|
||||
"ticket": { "$ref": "#/$defs/ticket" },
|
||||
"parent_epic": { "$ref": "#/$defs/parentEpic" },
|
||||
"worktree": { "type": ["string", "null"] }
|
||||
}
|
||||
},
|
||||
"metaStrict": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["schema_version", "slug", "state", "created_at", "updated_at", "ticket"],
|
||||
"description": "Strict profile (schema_version 2): closed core field set. Run-specific context (route/pr/node/task_node/...) goes in the context bag 鈥?the ONLY place for non-core fields.",
|
||||
"allOf": [
|
||||
{
|
||||
"if": { "properties": { "state": { "const": "archived" } }, "required": ["state"] },
|
||||
"then": {
|
||||
"properties": {
|
||||
"closed_at": { "type": "string", "format": "date-time" },
|
||||
"close_commit_sha": { "type": "string", "pattern": "^([0-9a-f]{40}|[0-9a-f]{64})$" }
|
||||
},
|
||||
"required": ["closed_at", "close_commit_sha"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"schema_version": { "type": "integer", "const": 2 },
|
||||
"slug": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
||||
"branch": { "type": "string", "minLength": 1 },
|
||||
"worktree": {
|
||||
"type": ["string", "null"],
|
||||
"description": "Absolute path of the worktree hosting this run, or null for ad-hoc runs without a worktree."
|
||||
},
|
||||
"state": { "type": "string", "enum": ["active", "archived"] },
|
||||
"created_at": { "type": "string", "format": "date-time" },
|
||||
"updated_at": { "type": "string", "format": "date-time" },
|
||||
"closed_at": { "type": ["string", "null"], "format": "date-time" },
|
||||
"close_commit_sha": { "type": ["string", "null"], "pattern": "^([0-9a-f]{40}|[0-9a-f]{64})$" },
|
||||
"ticket": { "$ref": "#/$defs/ticket" },
|
||||
"parent_epic": { "$ref": "#/$defs/parentEpic" },
|
||||
"context": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"description": "Free-form run context (route, pr, node, task_node, mode, kind, ...). In v2 every non-core field MUST live here, not at meta top level."
|
||||
}
|
||||
}
|
||||
},
|
||||
"artifactLegacy": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["path"],
|
||||
"properties": {
|
||||
"path": { "type": "string", "minLength": 1 },
|
||||
"sha": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^[0-9a-f]{12,64}$",
|
||||
"description": "Legacy digests may be truncated (12/16-hex; source files no longer exist, cannot be re-computed). v2 requires full 64-hex."
|
||||
}
|
||||
}
|
||||
},
|
||||
"artifactStrict": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["path", "type", "tier"],
|
||||
"properties": {
|
||||
"path": { "type": "string", "minLength": 1 },
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"meta",
|
||||
"index",
|
||||
"design",
|
||||
"plan",
|
||||
"review-findings",
|
||||
"review-status",
|
||||
"review-synthesis",
|
||||
"synthesis-prompt",
|
||||
"precondition-gate",
|
||||
"working-notes",
|
||||
"analysis",
|
||||
"browser-evidence",
|
||||
"other"
|
||||
]
|
||||
},
|
||||
"schema": { "type": ["string", "null"], "format": "uri" },
|
||||
"tier": { "type": "integer", "const": 1 },
|
||||
"stage": {
|
||||
"type": ["string", "null"],
|
||||
"enum": [
|
||||
"requirements",
|
||||
"design",
|
||||
"plan-iterations",
|
||||
"roadmap",
|
||||
"implement",
|
||||
"review-roadmap",
|
||||
"review-design-space",
|
||||
"review-iteration-plan",
|
||||
"review-dag",
|
||||
"review-code",
|
||||
"verify",
|
||||
"audit-process",
|
||||
"merge-pr",
|
||||
null
|
||||
],
|
||||
"description": "Producing pipeline stage. Live stage ids (per schemas/workflow-routing.schema.json): review-dag, review-code, verify, audit-process, merge-pr. Retired/phase names retained only so historical archived bundles keep validating."
|
||||
},
|
||||
"produced_by": {
|
||||
"type": ["string", "null"],
|
||||
"enum": [
|
||||
"Producer",
|
||||
"Reviewer",
|
||||
"Verifier",
|
||||
"Tool",
|
||||
"Coordinator",
|
||||
"Analyst",
|
||||
"Architect",
|
||||
"Planner",
|
||||
"Developer",
|
||||
"Synthesizer",
|
||||
"Orchestrator",
|
||||
"Remediator",
|
||||
"Auditor",
|
||||
null
|
||||
]
|
||||
},
|
||||
"sha": { "type": ["string", "null"], "pattern": "^[0-9a-f]{64}$" },
|
||||
"tier2_ref": { "type": ["string", "null"] }
|
||||
}
|
||||
},
|
||||
"indexLegacy": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"required": ["artifacts"],
|
||||
"properties": {
|
||||
"schema_version": { "type": "integer", "minimum": 1 },
|
||||
"slug": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
||||
"artifacts": { "type": "array", "items": { "$ref": "#/$defs/artifactLegacy" } }
|
||||
}
|
||||
},
|
||||
"indexStrict": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["schema_version", "slug", "artifacts"],
|
||||
"properties": {
|
||||
"schema_version": { "type": "integer", "const": 2 },
|
||||
"slug": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
||||
"artifacts": { "type": "array", "items": { "$ref": "#/$defs/artifactStrict" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://eightarms.net/octopus-workflow/schemas/runs-index.schema.json",
|
||||
"title": "Tier 1 Run Artifact Index",
|
||||
"description": "Schema for runs/{slug}/index.json 鈥?the artifact manifest for a Tier 1 local structured run. This is the compact-recovery entry point after compaction (compact never deletes local files). Parallel to, not a replacement for, the Tier 2 '## 宸ヤ欢绱㈠紩' issue comment. Authoritative layout: templates/runs-layout.md. Boundary rule: rules/two-tier-artifacts.md.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["schema_version", "slug", "artifacts"],
|
||||
"properties": {
|
||||
"$schema": {
|
||||
"type": "string",
|
||||
"description": "Optional JSON Schema $self reference for editor validation."
|
||||
},
|
||||
"schema_version": {
|
||||
"type": "integer",
|
||||
"const": 1,
|
||||
"description": "Index schema version."
|
||||
},
|
||||
"slug": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z0-9][a-z0-9-]*$",
|
||||
"description": "Run slug; must match meta.json.slug."
|
||||
},
|
||||
"artifacts": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/artifact" },
|
||||
"description": "One entry per Tier 1 artifact in this run. Tier 2 artifacts (Gitea issue comments, wiki pages, commit status, PRs) are NEVER listed here 鈥?this index is Tier 1 only."
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"artifact": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["path", "type", "tier"],
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Artifact path relative to {active-slug}/. Use forward slashes."
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"meta",
|
||||
"index",
|
||||
"design",
|
||||
"plan",
|
||||
"review-findings",
|
||||
"review-status",
|
||||
"review-synthesis",
|
||||
"synthesis-prompt",
|
||||
"precondition-gate",
|
||||
"working-notes",
|
||||
"analysis",
|
||||
"browser-evidence",
|
||||
"other"
|
||||
],
|
||||
"description": "Artifact category. 'meta'/'index' for the manifest files themselves; stage categories for produced artifacts. 'review-synthesis' marks a synthesis result artifact (round verdict) as distinct from 'synthesis-prompt' (the Phase B task prompt) and 'review-status' (the lifecycle file). 'precondition-gate' marks the review-code mechanical-green gate log. 'working-notes' is the cross-stage narrative memory file ([org-internal #2600]) 鈥?one file per run, appended by every role at close, registered once (stage/produced_by null: multi-stage, multi-role). 'browser-evidence' marks a browser evidence pack manifest ([org-internal #4497] N-03, browser/{session-id}/manifest.json 鈥?shared/pack-manifest-v1)."
|
||||
},
|
||||
"schema": {
|
||||
"type": ["string", "null"],
|
||||
"format": "uri",
|
||||
"description": "$id of the validating JSON Schema, or null for schema-less artifacts (e.g. a prompt .md passed via prompt_file). Accepts $ids from the current namespace https://eightarms.net/octopus-workflow/schemas/*.schema.json as well as legacy $ids from the historical namespace https://eightarms.net/fourbroad/octopus/ (archived live runs' index.json carry the old values); legacy values resolve via schemas/id-aliases.json."
|
||||
},
|
||||
"tier": {
|
||||
"type": "integer",
|
||||
"const": 1,
|
||||
"description": "Tier marker. This index lists only Tier 1 artifacts, so the value is always 1."
|
||||
},
|
||||
"stage": {
|
||||
"type": ["string", "null"],
|
||||
"enum": [
|
||||
"requirements",
|
||||
"design",
|
||||
"plan-iterations",
|
||||
"roadmap",
|
||||
"implement",
|
||||
"review-roadmap",
|
||||
"review-design-space",
|
||||
"review-iteration-plan",
|
||||
"review-dag",
|
||||
"review-code",
|
||||
"verify",
|
||||
"audit-process",
|
||||
"merge-pr",
|
||||
null
|
||||
],
|
||||
"description": "Producing pipeline stage, or null for meta/index manifest entries. Live stage ids (per schemas/workflow-routing.schema.json): review-dag, review-code, verify, audit-process, merge-pr. The production-phase / retired names (requirements, design, plan-iterations, roadmap, implement, review-roadmap, review-design-space, review-iteration-plan) are retained ONLY so historical archived rows keep validating; new artifacts MUST use the live ids."
|
||||
},
|
||||
"produced_by": {
|
||||
"type": ["string", "null"],
|
||||
"enum": [
|
||||
"Producer",
|
||||
"Reviewer",
|
||||
"Verifier",
|
||||
"Tool",
|
||||
"Coordinator",
|
||||
"Analyst",
|
||||
"Architect",
|
||||
"Planner",
|
||||
"Developer",
|
||||
"Synthesizer",
|
||||
"Orchestrator",
|
||||
"Remediator",
|
||||
"Auditor",
|
||||
null
|
||||
],
|
||||
"description": "Role that produced the artifact, or null if not role-attributed. Canonical role names are Producer / Reviewer / Verifier / Tool / Coordinator (the `name` field of skills/_shared/roles/*.yaml). The remaining values are fine-grained sub-roles mapped to canonical roles via ROLE_ALIASES in role config: Analyst / Architect / Planner / Developer / Synthesizer / Orchestrator / Remediator map to `Producer`; Auditor maps to `Reviewer`. They are retained so historical index rows validate and so the audit target's revision role (Remediator) and reviewer sub-role (Auditor) can be attributed if ever written to a Tier 1 artifact."
|
||||
},
|
||||
"sha": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^[0-9a-f]{64}$",
|
||||
"description": "sha256 content digest, or null if not yet computed."
|
||||
},
|
||||
"tier2_ref": {
|
||||
"type": ["string", "null"],
|
||||
"description": "Cross-link to a Tier 2 mirror of this artifact (issue comment URL, wiki page path, commit status context) when one exists; null when the artifact is Tier 1 only."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://eightarms.net/octopus-workflow/schemas/runs-meta.schema.json",
|
||||
"title": "Tier 1 Run Metadata",
|
||||
"description": "Schema for runs/{slug}/meta.json 鈥?run metadata for a Tier 1 local structured run. Authoritative layout: templates/runs-layout.md. Boundary rule: rules/two-tier-artifacts.md. State transitions active -> archived at close (archive-at-close).",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"schema_version",
|
||||
"slug",
|
||||
"state",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"ticket",
|
||||
"parent_epic",
|
||||
"closed_at",
|
||||
"close_commit_sha"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"if": { "properties": { "state": { "const": "archived" } }, "required": ["state"] },
|
||||
"then": {
|
||||
"properties": {
|
||||
"closed_at": { "type": "string", "format": "date-time" },
|
||||
"close_commit_sha": { "type": "string", "pattern": "^([0-9a-f]{40}|[0-9a-f]{64})$" }
|
||||
},
|
||||
"required": ["closed_at", "close_commit_sha"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"$schema": {
|
||||
"type": "string",
|
||||
"description": "Optional JSON Schema $self reference for editor validation."
|
||||
},
|
||||
"schema_version": {
|
||||
"type": "integer",
|
||||
"const": 1,
|
||||
"description": "Layout schema version. Bumped on breaking changes to this shape."
|
||||
},
|
||||
"slug": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z0-9][a-z0-9-]*$",
|
||||
"description": "Run slug. Matches the workflow branch tail and the Gitea wiki namespace."
|
||||
},
|
||||
"ticket": {
|
||||
"oneOf": [
|
||||
{ "type": "null" },
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["owner", "repo", "number"],
|
||||
"properties": {
|
||||
"owner": { "type": "string", "minLength": 1 },
|
||||
"repo": { "type": "string", "minLength": 1 },
|
||||
"number": { "type": "integer", "minimum": 1 }
|
||||
}
|
||||
}
|
||||
],
|
||||
"description": "Source issue reference, or null for an ad-hoc run (no ticket)."
|
||||
},
|
||||
"branch": {
|
||||
"type": "string",
|
||||
"description": "Workflow branch, e.g. workflow/enhancement/1968-two-tier-artifacts. Omitted for ad-hoc runs without a branch (both runs-bundle profiles tolerate omission)."
|
||||
},
|
||||
"worktree": {
|
||||
"type": ["string", "null"],
|
||||
"description": "Absolute path of the worktree hosting this run, or null for ad-hoc runs without a worktree (aligned with runs-bundle.schema.json metaStrict)."
|
||||
},
|
||||
"parent_epic": {
|
||||
"oneOf": [
|
||||
{ "type": "null" },
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["number"],
|
||||
"properties": {
|
||||
"number": { "type": "integer", "minimum": 1 }
|
||||
}
|
||||
}
|
||||
],
|
||||
"description": "Parent Epic issue number, or null if the run is not under an Epic."
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": ["active", "archived"],
|
||||
"description": "active: run in progress (workspace gitignored). archived: closed; bundle committed under runs/archive/{slug}.json."
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "RFC 3339 timestamp 鈥?run creation."
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "RFC 3339 timestamp 鈥?last metadata mutation."
|
||||
},
|
||||
"closed_at": {
|
||||
"type": ["string", "null"],
|
||||
"format": "date-time",
|
||||
"description": "RFC 3339 timestamp set at archive-at-close, or null while active."
|
||||
},
|
||||
"close_commit_sha": {
|
||||
"type": ["string", "null"],
|
||||
"pattern": "^([0-9a-f]{40}|[0-9a-f]{64})$",
|
||||
"description": "git SHA of the commit that landed archive/{slug}.json; null while active. Must be non-null when state=archived (enforced by the if/then invariant)."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://eightarms.net/octopus-workflow/schemas/synthesis.schema.json",
|
||||
"title": "Synthesis Output",
|
||||
"description": "Schema for the orchestrator's synthesis of all reviewer outputs for a single round.",
|
||||
"type": "object",
|
||||
"required": ["round", "overall_verdict", "dimensions", "aggregated_stats", "top_findings"],
|
||||
"properties": {
|
||||
"round": { "type": "integer", "minimum": 1 },
|
||||
"overall_verdict": {
|
||||
"type": "string",
|
||||
"enum": ["PASS", "WARN", "FAIL"],
|
||||
"description": "PASS: all dimensions PASS. WARN: no BLOCKER, no dimension FAIL. FAIL: otherwise."
|
||||
},
|
||||
"dimensions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"required": ["verdict", "pass_rate", "blocker_count", "major_count", "minor_count", "info_count"],
|
||||
"properties": {
|
||||
"verdict": { "type": "string", "enum": ["PASS", "WARN", "FAIL", "UNRESOLVED"] },
|
||||
"pass_rate": { "type": "number" },
|
||||
"blocker_count": { "type": "integer" },
|
||||
"major_count": { "type": "integer" },
|
||||
"minor_count": { "type": "integer" },
|
||||
"info_count": { "type": "integer" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"aggregated_stats": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"total_dimensions",
|
||||
"passed_dimensions",
|
||||
"warn_dimensions",
|
||||
"failed_dimensions",
|
||||
"total_findings",
|
||||
"blockers",
|
||||
"majors",
|
||||
"minors",
|
||||
"infos"
|
||||
],
|
||||
"properties": {
|
||||
"total_dimensions": { "type": "integer" },
|
||||
"passed_dimensions": { "type": "integer" },
|
||||
"warn_dimensions": { "type": "integer" },
|
||||
"failed_dimensions": { "type": "integer" },
|
||||
"total_findings": { "type": "integer" },
|
||||
"blockers": { "type": "integer" },
|
||||
"majors": { "type": "integer" },
|
||||
"minors": { "type": "integer" },
|
||||
"infos": { "type": "integer" },
|
||||
"unresolved_dimensions": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Count of dimensions marked UNRESOLVED (auditor crash/timeout) and excluded from aggregation"
|
||||
}
|
||||
}
|
||||
},
|
||||
"top_findings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["id", "dimension", "severity", "checklist_ref", "summary"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z0-9]+-F\\d{3,}$",
|
||||
"description": "The source reviewer finding id (from the Tier 1 findings file; slot-prefixed for multi-slot dimensions), so each synthesized headline traces back to its raw finding."
|
||||
},
|
||||
"dimension": { "type": "string" },
|
||||
"severity": { "type": "string", "enum": ["BLOCKER", "MAJOR", "MINOR", "INFO"] },
|
||||
"checklist_ref": { "type": "string" },
|
||||
"summary": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://eightarms.net/octopus-workflow/schemas/workflow-routing.schema.json",
|
||||
"title": "Workflow Routing Table",
|
||||
"description": "Schema for workflow-routing.yaml 鈥?type-driven (Kind/*) process selection. Referenced by rules/workflow-routing.md and the auto-approve rule. When this schema and the rules markdown disagree, the YAML (validated by this schema) is authoritative.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["version", "default", "routes"],
|
||||
"properties": {
|
||||
"$schema": { "type": "string" },
|
||||
"version": { "type": "integer", "const": 1 },
|
||||
"default": { "$ref": "#/$defs/route" },
|
||||
"routes": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#/$defs/route" },
|
||||
"description": "Keys are Kind/* label names, e.g. Kind/Bug, Kind/Feature."
|
||||
},
|
||||
"preflight": { "$ref": "#/$defs/preflightPolicy" },
|
||||
"dag": { "$ref": "#/$defs/dag" },
|
||||
"filing": { "$ref": "#/$defs/filing" },
|
||||
"review": { "$ref": "#/$defs/review" }
|
||||
},
|
||||
"$defs": {
|
||||
"stage": {
|
||||
"type": "string",
|
||||
"description": "A pipeline stage identifier 鈥?the 5 live gates (post-[org-internal #3072] phase 3, 2026-08-21): review-dag, review-code, verify, audit-process, merge-pr. Production-phase names (requirements, design, roadmap, implement) and the 7 retired stage ids (roadmap-exit, review-roadmap, requirements-exit, design-exit, review-design-space, review-iteration-plan, plan-iterations) are no longer valid anywhere 鈥?the sizing block that consumed the phase names was retired the same ruling.",
|
||||
"enum": ["review-dag", "review-code", "verify", "audit-process", "merge-pr"]
|
||||
},
|
||||
"entry": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"skill": {
|
||||
"type": ["string", "null"],
|
||||
"enum": ["implement", "review-artifact", "review-code", "verify", "analyze-dag", null],
|
||||
"description": "Skill name to enter, or null for natural-language routing. The legacy roadmap / requirements-elicitation / design / plan-iterations entries were removed when those skills were archived ([org-internal #3072] phase 3, 2026-08-21 - the instance archive)."
|
||||
},
|
||||
"mode": {
|
||||
"type": ["string", "null"],
|
||||
"enum": ["bugfix", "refactor", "port", null],
|
||||
"description": "Skill mode, or null."
|
||||
}
|
||||
}
|
||||
},
|
||||
"stageList": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/stage" }
|
||||
},
|
||||
"route": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"entry": { "$ref": "#/$defs/entry" },
|
||||
"skip": { "$ref": "#/$defs/stageList" },
|
||||
"keep_gates": { "$ref": "#/$defs/stageList" },
|
||||
"preflight": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/preflightItem" },
|
||||
"description": "Evidence-based producer pre-flight checklist ([org-internal #2599]) 鈥?landed by a human from retrospective PRE-FLIGHT PROPOSAL rows. Absent/empty = no injection. Cap is governed by preflight.max_items (policy), not the schema."
|
||||
},
|
||||
"notes": { "type": "string" },
|
||||
"effort": {
|
||||
"type": "string",
|
||||
"enum": ["low", "high", "max"],
|
||||
"description": "Reasoning-effort hint for this route (llm-latency phase 2): maps onto the active model's variant table when it exposes one (GLM-5.2+ low/high/max); fail-open otherwise. Reserve `low` for genuinely lightweight routes (direct-edit, no pipeline) 鈥?reasoning dominates GLM-5.3 generation latency."
|
||||
}
|
||||
}
|
||||
},
|
||||
"preflightPolicy": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "Thresholds for the retro 鈫?routes.{Kind}.preflight evidence loop ([org-internal #2599]). Authoritative values live here; the retrospective consults this block, it does not restate the numbers.",
|
||||
"properties": {
|
||||
"max_items": { "type": "integer", "minimum": 1 },
|
||||
"min_sample": { "type": "integer", "minimum": 0 },
|
||||
"consecutive_recur": { "type": "integer", "minimum": 1 },
|
||||
"aging_consecutive_clean": { "type": "integer", "minimum": 1 }
|
||||
}
|
||||
},
|
||||
"preflightItem": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["id", "item", "evidence"],
|
||||
"properties": {
|
||||
"id": { "type": "string", "description": "Stable slug, e.g. cor-unhandled-null." },
|
||||
"item": { "type": "string", "description": "One checklist line the Producer verifies before implementing." },
|
||||
"evidence": {
|
||||
"type": "string",
|
||||
"description": "Retro reference justifying the item, e.g. 'retro [org-internal #2599]: COR 脳 unhandled-null, 5/8 first-round FAILs on Kind/Bug'."
|
||||
},
|
||||
"added_cycle": {
|
||||
"type": "string",
|
||||
"description": "Cycle id when landed, e.g. 2026-08. Drop-oldest beyond preflight.max_items sorts on this."
|
||||
}
|
||||
}
|
||||
},
|
||||
"filing": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "Filing policy (绔嬫/鐧昏绛栫暐). sprint-mode ([org-internal #3007]): when true, verify Phase 5.5 promotes registry rows to tickets in sprint mode only. work-ticket-wip-cap ([org-internal #3005] G3): open non-TD work tickets beyond this count require scheduling evidence, else they stay registry rows.",
|
||||
"properties": {
|
||||
"sprint-mode": {
|
||||
"type": "boolean",
|
||||
"description": "Sprint-mode filing downgrade switch ([org-internal #3007])."
|
||||
},
|
||||
"work-ticket-wip-cap": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "WIP cap on open non-TD work tickets (Kind/* without assignee) before new filings require scheduling evidence ([org-internal #3005] G3)."
|
||||
}
|
||||
}
|
||||
},
|
||||
"review": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "Review round budget (process-diet P0b, [org-internal #3567]/TD-564): a tail cut, not the norm 鈥?at budget without convergence, STOP; residual findings flow to the TD registry. High risk = a BLOCKER survived a round or the diff touches a frozen cross-session contract.",
|
||||
"required": ["max_rounds"],
|
||||
"properties": {
|
||||
"max_rounds": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["default", "high_risk"],
|
||||
"properties": {
|
||||
"default": { "type": "integer" },
|
||||
"high_risk": { "type": "integer" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dag": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["route", "task_route", "ticket_creation", "verify_milestone", "size_derivation", "review_depth"],
|
||||
"properties": {
|
||||
"route": { "$ref": "#/$defs/dagRoute" },
|
||||
"task_route": { "$ref": "#/$defs/dagTaskRoute" },
|
||||
"ticket_creation": { "$ref": "#/$defs/dagTicketCreation" },
|
||||
"verify_milestone": { "$ref": "#/$defs/dagVerifyMilestone" },
|
||||
"size_derivation": { "$ref": "#/$defs/dagSizeDerivation" },
|
||||
"review_depth": { "$ref": "#/$defs/dagReviewDepth" }
|
||||
}
|
||||
},
|
||||
"dagRoute": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["entry", "skip", "keep_gates", "single_gate"],
|
||||
"properties": {
|
||||
"entry": { "$ref": "#/$defs/entry" },
|
||||
"skip": { "$ref": "#/$defs/stageList" },
|
||||
"keep_gates": { "$ref": "#/$defs/stageList" },
|
||||
"single_gate": { "$ref": "#/$defs/dagSingleGate" },
|
||||
"preflight": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/preflightItem" },
|
||||
"description": "Evidence-based pre-flight checklist for the DAG route ([org-internal #2905] 鏂规 3) 鈥?same item shape as routes.{Kind}.preflight ([org-internal #2599]). Landed by a human from retrospective PRE-FLIGHT PROPOSAL rows, including the 'REQ 脳 late-discovery' root cause (requirements found only after the DAG froze: DAG oversize signals, demo-period feedback). Consumed by analyze-dag (the route's entry skill) before decomposition. Absent/empty = no injection. Optional 鈥?deliberately NOT in dagRoute.required (spec-02 搂2.8 frozen required array unchanged). Cap governed by preflight.max_items (policy), not the schema."
|
||||
}
|
||||
}
|
||||
},
|
||||
"dagTaskRoute": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["entry", "skip", "keep_gates", "inherit"],
|
||||
"properties": {
|
||||
"entry": { "$ref": "#/$defs/entry" },
|
||||
"skip": { "$ref": "#/$defs/stageList" },
|
||||
"keep_gates": { "$ref": "#/$defs/stageList" },
|
||||
"inherit": { "type": "string", "enum": ["parent_dag"] }
|
||||
}
|
||||
},
|
||||
"dagSingleGate": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["id", "dimensions", "replaces", "depth_from", "never_trim"],
|
||||
"properties": {
|
||||
"id": { "type": "string", "enum": ["review-dag"] },
|
||||
"dimensions": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "enum": ["TOPO", "REQMAP", "RELEASE"] },
|
||||
"uniqueItems": true,
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
},
|
||||
"replaces": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Historical documentation of which legacy gates the single gate replaced ([org-internal #3072] phase 3 retired them) 鈥?free-form strings, not the live stage vocabulary."
|
||||
},
|
||||
"depth_from": { "type": "string", "enum": ["size_derivation"] },
|
||||
"never_trim": { "type": "boolean" }
|
||||
}
|
||||
},
|
||||
"dagTicketCreation": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["per_node", "milestone_no_ticket", "inherit_parent", "parent_aggregator"],
|
||||
"properties": {
|
||||
"per_node": { "type": "boolean" },
|
||||
"milestone_no_ticket": { "type": "boolean" },
|
||||
"inherit_parent": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "enum": ["Kind/Epic", "Kind/Feature"] },
|
||||
"uniqueItems": true,
|
||||
"minItems": 1,
|
||||
"description": "Ticket kinds whose DAG children reference them as ## 鐖剁骇 / Parent ([org-internal #3061] Phase 2 / TD-388: Kind/Feature added alongside Kind/Epic)."
|
||||
},
|
||||
"parent_aggregator": { "type": "boolean" }
|
||||
}
|
||||
},
|
||||
"dagVerifyMilestone": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["weld_at_convergence", "milestone_skill", "integration_trigger"],
|
||||
"properties": {
|
||||
"weld_at_convergence": { "type": "boolean" },
|
||||
"milestone_skill": { "type": "string", "enum": ["verify"] },
|
||||
"integration_trigger": { "type": "string", "enum": ["all_incoming_done_and_green"] }
|
||||
}
|
||||
},
|
||||
"dagSizeDerivation": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["enabled", "thresholds", "size_labels", "oversize_signals"],
|
||||
"properties": {
|
||||
"enabled": { "type": "boolean" },
|
||||
"formula": { "type": "string" },
|
||||
"thresholds": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"node_count": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"d1": { "type": "integer" },
|
||||
"d2": { "type": "integer" },
|
||||
"d3": { "type": "integer" }
|
||||
}
|
||||
},
|
||||
"cross_session_edge_count": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"d1": { "type": "integer" },
|
||||
"d3": { "type": "integer" }
|
||||
}
|
||||
},
|
||||
"contract_change_surface": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"none": { "type": "string" },
|
||||
"additive": { "type": "string" },
|
||||
"breaking": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"size_labels": { "type": "string" },
|
||||
"oversize_signals": { "type": "array", "items": { "$ref": "#/$defs/dagOversizeSignal" } }
|
||||
}
|
||||
},
|
||||
"dagOversizeSignal": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["id", "trigger"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"node_split",
|
||||
"new_cross_session_edge",
|
||||
"draft_contract_breaking",
|
||||
"frozen_contract_breaking",
|
||||
"node_scope_drift"
|
||||
]
|
||||
},
|
||||
"trigger": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"dagReviewDepth": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["D1", "D2", "D3", "D4"],
|
||||
"properties": {
|
||||
"D1": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["reviewers", "rounds", "dim_split"],
|
||||
"properties": {
|
||||
"reviewers": { "type": "integer" },
|
||||
"rounds": { "type": "integer" },
|
||||
"dim_split": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"D2": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["reviewers", "rounds", "dim_split"],
|
||||
"properties": {
|
||||
"reviewers": { "type": "integer" },
|
||||
"rounds": { "type": "integer" },
|
||||
"dim_split": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"D3": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["reviewers", "rounds", "dim_split"],
|
||||
"properties": {
|
||||
"reviewers": { "type": "integer" },
|
||||
"rounds": { "type": "integer" },
|
||||
"dim_split": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"D4": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["reviewers", "rounds", "dim_split"],
|
||||
"properties": {
|
||||
"reviewers": { "type": "integer" },
|
||||
"rounds": { "type": "integer" },
|
||||
"dim_split": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user