syntaur 0.43.1 → 0.44.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/.claude-plugin/plugin.json +1 -1
- package/dashboard/dist/assets/{_basePickBy-CabSPDlA.js → _basePickBy-CNjxCBYf.js} +1 -1
- package/dashboard/dist/assets/{_baseUniq-DGO4Y46J.js → _baseUniq-1yktSv9L.js} +1 -1
- package/dashboard/dist/assets/{arc-C0lxzBYC.js → arc-CUp_7cxd.js} +1 -1
- package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-DAa-zxeT.js → architectureDiagram-2XIMDMQ5-BhQNIov3.js} +1 -1
- package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-BhFavWXG.js → blockDiagram-WCTKOSBZ-BbrHpJX7.js} +1 -1
- package/dashboard/dist/assets/{c4Diagram-IC4MRINW-BxKqhk8H.js → c4Diagram-IC4MRINW-BzAgIl-O.js} +1 -1
- package/dashboard/dist/assets/channel-Dcp4Ds-Z.js +1 -0
- package/dashboard/dist/assets/{chunk-4BX2VUAB-CayPDVSU.js → chunk-4BX2VUAB-DxR-gcvU.js} +1 -1
- package/dashboard/dist/assets/{chunk-55IACEB6-DE34igmQ.js → chunk-55IACEB6-DgMbDP9S.js} +1 -1
- package/dashboard/dist/assets/{chunk-FMBD7UC4-CWHswGwW.js → chunk-FMBD7UC4-zECir1CK.js} +1 -1
- package/dashboard/dist/assets/{chunk-JSJVCQXG-DnsqdfIB.js → chunk-JSJVCQXG-Cnl5h8xD.js} +1 -1
- package/dashboard/dist/assets/{chunk-KX2RTZJC-FbqVE08c.js → chunk-KX2RTZJC-Ck2VpQt9.js} +1 -1
- package/dashboard/dist/assets/{chunk-NQ4KR5QH-DcsdDqWQ.js → chunk-NQ4KR5QH-B8kgPwoS.js} +1 -1
- package/dashboard/dist/assets/{chunk-QZHKN3VN-DZBdzXAZ.js → chunk-QZHKN3VN-CsN9VGXC.js} +1 -1
- package/dashboard/dist/assets/{chunk-WL4C6EOR-DV11wZKH.js → chunk-WL4C6EOR-BP27dBI1.js} +1 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-CnkOuwPH.js +1 -0
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-CnkOuwPH.js +1 -0
- package/dashboard/dist/assets/clone-cpjQdgQb.js +1 -0
- package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-Cc5iZnSF.js → cose-bilkent-S5V4N54A-m2V_HPK-.js} +1 -1
- package/dashboard/dist/assets/{dagre-KLK3FWXG-DdhTE6jK.js → dagre-KLK3FWXG-CZfxqYb1.js} +1 -1
- package/dashboard/dist/assets/{diagram-E7M64L7V-DNwcjAks.js → diagram-E7M64L7V-DtzcWFtr.js} +1 -1
- package/dashboard/dist/assets/{diagram-IFDJBPK2-UNMmAgBt.js → diagram-IFDJBPK2-D2IymgnX.js} +1 -1
- package/dashboard/dist/assets/{diagram-P4PSJMXO-DFVklVy0.js → diagram-P4PSJMXO-D24UPsRu.js} +1 -1
- package/dashboard/dist/assets/{erDiagram-INFDFZHY-CN8yM6gL.js → erDiagram-INFDFZHY-CZKUJMzt.js} +1 -1
- package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-CueIaRLY.js → flowDiagram-PKNHOUZH-DL_F8pzV.js} +1 -1
- package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-DnYhCq5T.js → ganttDiagram-A5KZAMGK-D8fgmRAI.js} +1 -1
- package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-ISNXg3k0.js → gitGraphDiagram-K3NZZRJ6-2-zNwJhX.js} +1 -1
- package/dashboard/dist/assets/{graph-BZz0E7Ci.js → graph-BGFPrUov.js} +1 -1
- package/dashboard/dist/assets/{index-Dzh96P4Z.js → index-C4lUbUTt.js} +101 -101
- package/dashboard/dist/assets/{index-BqxbS9Wf.css → index-D1f1wB-7.css} +1 -1
- package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-bNvKINb_.js → infoDiagram-LFFYTUFH-C_AYIIRq.js} +1 -1
- package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-DKfRfWXE.js → ishikawaDiagram-PHBUUO56-BF1Td7it.js} +1 -1
- package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-BfKl4TNb.js → journeyDiagram-4ABVD52K-EMMIV9Ho.js} +1 -1
- package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-3b_Gc82P.js → kanban-definition-K7BYSVSG-Bf_bRjc1.js} +1 -1
- package/dashboard/dist/assets/{layout-CDFST2WK.js → layout-DVtc1c49.js} +1 -1
- package/dashboard/dist/assets/{linear-DFkg06qv.js → linear-B-_q9tMu.js} +1 -1
- package/dashboard/dist/assets/{mermaid.core-eqq1_dL_.js → mermaid.core-DsNAtlU2.js} +4 -4
- package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-3UicY0_v.js → mindmap-definition-YRQLILUH-CIk_H2CD.js} +1 -1
- package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-CZyg0jjE.js → pieDiagram-SKSYHLDU-CuqaiuOZ.js} +1 -1
- package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-Cj6oadbs.js → quadrantDiagram-337W2JSQ-By2Uoys0.js} +1 -1
- package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-BlfA8l6H.js → requirementDiagram-Z7DCOOCP-RQe6sA24.js} +1 -1
- package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-CHU0rdbD.js → sankeyDiagram-WA2Y5GQK-BWqm0u7o.js} +1 -1
- package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-fP5IFexC.js → sequenceDiagram-2WXFIKYE-DZ4Esix3.js} +1 -1
- package/dashboard/dist/assets/{stateDiagram-RAJIS63D-CdthThpd.js → stateDiagram-RAJIS63D-Xae5htdZ.js} +1 -1
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-BfD_wvla.js +1 -0
- package/dashboard/dist/assets/{timeline-definition-YZTLITO2-DI1ep504.js → timeline-definition-YZTLITO2-DxW_e6Qq.js} +1 -1
- package/dashboard/dist/assets/{treemap-KZPCXAKY-CvuW7d81.js → treemap-KZPCXAKY-BTD-CY69.js} +1 -1
- package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-DEuyxMbM.js → vennDiagram-LZ73GAT5-BhpyjM1r.js} +1 -1
- package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-BVlWbeAK.js → xychartDiagram-JWTSCODW-BmQJbBCA.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dist/dashboard/server.js +4853 -4299
- package/dist/dashboard/server.js.map +1 -1
- package/dist/index.js +2817 -2142
- package/dist/index.js.map +1 -1
- package/dist/launch/index.d.ts +15 -0
- package/dist/launch/index.js +3130 -2709
- package/dist/launch/index.js.map +1 -1
- package/package.json +1 -1
- package/platforms/claude-code/.claude-plugin/plugin.json +1 -1
- package/platforms/claude-code/skills/manage-statuses/SKILL.md +49 -1
- package/platforms/codex/.codex-plugin/plugin.json +1 -1
- package/platforms/codex/skills/manage-statuses/SKILL.md +49 -1
- package/platforms/hermes/plugins/syntaur/__pycache__/__init__.cpython-312.pyc +0 -0
- package/platforms/hermes/plugins/syntaur/__pycache__/boundary.cpython-312.pyc +0 -0
- package/skills/manage-statuses/SKILL.md +49 -1
- package/dashboard/dist/assets/channel-gkqjyV0r.js +0 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-D1CF55uI.js +0 -1
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-D1CF55uI.js +0 -1
- package/dashboard/dist/assets/clone-Cx1NBdWo.js +0 -1
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-kKo_Asao.js +0 -1
package/package.json
CHANGED
|
@@ -62,11 +62,59 @@ After every mutating subcommand, run `syntaur status list` (or `--json` for mach
|
|
|
62
62
|
- **After a `remove --force`,** the affected assignments now reference an undefined status. `syntaur doctor` will flag them as invalid. Suggest the user run `syntaur doctor` and either re-add the status (`syntaur status add ...`) or edit each frontmatter to a valid id.
|
|
63
63
|
- **After `transition add`,** the dashboard's transition buttons reflect the new transition only after the cache invalidation above.
|
|
64
64
|
|
|
65
|
+
## Custom facts and attestations
|
|
66
|
+
|
|
67
|
+
Beyond the 14 built-in derived-status facts, users can declare their **own** facts under `statuses.facts` and reference them in `phaseLadder` / `disposition` conditions. There are two kinds.
|
|
68
|
+
|
|
69
|
+
**1. Custom asserted facts** — config-declared `bool` / `number` values, asserted via `syntaur fact set` and stored in a `facts:` frontmatter map:
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
statuses:
|
|
73
|
+
facts:
|
|
74
|
+
- name: qaPassed
|
|
75
|
+
type: bool
|
|
76
|
+
- name: storyPoints
|
|
77
|
+
type: number
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
syntaur fact set <assignment> qaPassed true --project <p>
|
|
82
|
+
syntaur fact set <assignment> storyPoints 5 --project <p>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`bool` accepts case-insensitive `true`/`false`; `number` accepts any finite number. The declared `name` exports a single derive field of the same name (`qaPassed:true`, `storyPoints > 3`). Stored in frontmatter as `facts:\n qaPassed: "true"`.
|
|
86
|
+
|
|
87
|
+
**2. Attestation facts** — model "agent X reviewed revision Y with verdict Z". Declared with `type: attestation` and a `binds:` mode:
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
statuses:
|
|
91
|
+
facts:
|
|
92
|
+
- name: codeReview
|
|
93
|
+
type: attestation
|
|
94
|
+
binds: plan # plan | commit | none
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
syntaur attest <assignment> codeReview --agent codex --verdict approved --project <p>
|
|
99
|
+
syntaur attest <assignment> codeReview --agent pi --verdict changes-requested --note "fix the lock" --project <p>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`--verdict` defaults to `approved` (the other value is `changes-requested`). One record per actor — re-attesting **replaces** that actor's record. Stored in an `attestations:` frontmatter list (`{fact, actor, verdict, at, note?}` + binding snapshot).
|
|
103
|
+
|
|
104
|
+
Each attestation fact exports **five** derive fields (for `codeReview`): `codeReview` (any valid record), `codeReviewApproved`, `codeReviewChangesRequested` (bools), and `codeReviewBy`, `codeReviewApprovedBy` (actor **sets** — use `:` for contains / `IN`-lists, e.g. `codeReviewApprovedBy:"agent:codex"`; quote actor values that contain a `:`). This makes review loops self-modeling — a rung `when: "codeReviewApproved:true"` fires on approval, and `when: "codeReviewChangesRequested:true"` expresses "reviewed but not signed off".
|
|
105
|
+
|
|
106
|
+
**Revision binding** is what makes attestations self-invalidate:
|
|
107
|
+
- `binds: plan` — bound to the latest plan file + its digest (same semantics as plan approval). A replan or a post-attest plan edit makes the record **stale**; stale records contribute nothing (the fact flips false, the actor drops out of the `*By` sets).
|
|
108
|
+
- `binds: commit` — bound to the workspace branch HEAD sha at attest time. A new commit makes it stale. **Lazy convergence:** dashboard payloads and `ls --query` compute facts fresh per request (always honest), but the *persisted* phase regression lands on the next recompute trigger (any CLI verb, watcher event, config change, or boot sweep) — there is no git watcher.
|
|
109
|
+
- `binds: none` — never stale (a standing sign-off).
|
|
110
|
+
|
|
111
|
+
**Validation & teeth.** Declared names are validated by `syntaur doctor` (the `derive-config.valid` check): bad name/type/binds and any collision of an exported field with a built-in or another declaration is reported as an error and the offending declaration is dropped (built-ins always win). A derive condition that references an **undeclared** fact still fails at recompute time (`CompileError`), exactly as before. `syntaur fact set` / `syntaur attest` reject undeclared names, wrong types, and invalid verdicts. Every `fact set` / `attest` is recorded in `statusHistory` with its actor and cause, even when no dimension moves.
|
|
112
|
+
|
|
65
113
|
## Safety notes
|
|
66
114
|
|
|
67
115
|
- **`remove` is destructive.** Without `--force` it refuses if any assignment references the id. Don't suggest `--force` without first running `syntaur status remove <id>` (no force) so the user sees the affected list.
|
|
68
116
|
- **`rename` rewrites many files.** It edits `config.md` AND every affected `assignment.md` in a single atomic transaction (with rollback if any write fails partway). Always run `--dry-run` first on a non-trivial codebase so the user sees the per-file diff.
|
|
69
117
|
- **`terminal: true` is load-bearing.** Terminal statuses affect dashboard progress bars and dependency-satisfaction logic — an assignment with a terminal status counts as "done" for downstream `dependsOn` checks and project-rollup status. Don't toggle this on `pending`-style states without thinking.
|
|
70
|
-
- **`init --force` overwrites a custom block.** Use `reset` first if the user wants a clean slate, OR confirm before passing `--force` if they have unsaved customizations.
|
|
118
|
+
- **`init --force` overwrites a custom block.** Use `reset` first if the user wants a clean slate, OR confirm before passing `--force` if they have unsaved customizations. It resets to the built-in defaults and therefore **drops any `statuses.facts` declarations and `derive` rules** along with the custom statuses — every other `status` subcommand (`set`/`add`/`remove`/`rename`/`reorder`/`transition`) preserves them.
|
|
71
119
|
- **Concurrency.** `rename`'s buffer-write-rollback strategy assumes no concurrent writers. Tell the user to close the dashboard / pause other agents during a rename.
|
|
72
120
|
- **`SYNTAUR_HOME` precedence.** If the user has `SYNTAUR_HOME` set, the CLI writes there instead of `~/.syntaur`. Mirror their environment.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "syntaur",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "Run Syntaur project and assignment workflows from Codex, including claiming work, planning, completing handoffs, session/server tracking, save-session-summary continuity, and write-boundary enforcement.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Brennen"
|
|
@@ -62,11 +62,59 @@ After every mutating subcommand, run `syntaur status list` (or `--json` for mach
|
|
|
62
62
|
- **After a `remove --force`,** the affected assignments now reference an undefined status. `syntaur doctor` will flag them as invalid. Suggest the user run `syntaur doctor` and either re-add the status (`syntaur status add ...`) or edit each frontmatter to a valid id.
|
|
63
63
|
- **After `transition add`,** the dashboard's transition buttons reflect the new transition only after the cache invalidation above.
|
|
64
64
|
|
|
65
|
+
## Custom facts and attestations
|
|
66
|
+
|
|
67
|
+
Beyond the 14 built-in derived-status facts, users can declare their **own** facts under `statuses.facts` and reference them in `phaseLadder` / `disposition` conditions. There are two kinds.
|
|
68
|
+
|
|
69
|
+
**1. Custom asserted facts** — config-declared `bool` / `number` values, asserted via `syntaur fact set` and stored in a `facts:` frontmatter map:
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
statuses:
|
|
73
|
+
facts:
|
|
74
|
+
- name: qaPassed
|
|
75
|
+
type: bool
|
|
76
|
+
- name: storyPoints
|
|
77
|
+
type: number
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
syntaur fact set <assignment> qaPassed true --project <p>
|
|
82
|
+
syntaur fact set <assignment> storyPoints 5 --project <p>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`bool` accepts case-insensitive `true`/`false`; `number` accepts any finite number. The declared `name` exports a single derive field of the same name (`qaPassed:true`, `storyPoints > 3`). Stored in frontmatter as `facts:\n qaPassed: "true"`.
|
|
86
|
+
|
|
87
|
+
**2. Attestation facts** — model "agent X reviewed revision Y with verdict Z". Declared with `type: attestation` and a `binds:` mode:
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
statuses:
|
|
91
|
+
facts:
|
|
92
|
+
- name: codeReview
|
|
93
|
+
type: attestation
|
|
94
|
+
binds: plan # plan | commit | none
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
syntaur attest <assignment> codeReview --agent codex --verdict approved --project <p>
|
|
99
|
+
syntaur attest <assignment> codeReview --agent pi --verdict changes-requested --note "fix the lock" --project <p>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`--verdict` defaults to `approved` (the other value is `changes-requested`). One record per actor — re-attesting **replaces** that actor's record. Stored in an `attestations:` frontmatter list (`{fact, actor, verdict, at, note?}` + binding snapshot).
|
|
103
|
+
|
|
104
|
+
Each attestation fact exports **five** derive fields (for `codeReview`): `codeReview` (any valid record), `codeReviewApproved`, `codeReviewChangesRequested` (bools), and `codeReviewBy`, `codeReviewApprovedBy` (actor **sets** — use `:` for contains / `IN`-lists, e.g. `codeReviewApprovedBy:"agent:codex"`; quote actor values that contain a `:`). This makes review loops self-modeling — a rung `when: "codeReviewApproved:true"` fires on approval, and `when: "codeReviewChangesRequested:true"` expresses "reviewed but not signed off".
|
|
105
|
+
|
|
106
|
+
**Revision binding** is what makes attestations self-invalidate:
|
|
107
|
+
- `binds: plan` — bound to the latest plan file + its digest (same semantics as plan approval). A replan or a post-attest plan edit makes the record **stale**; stale records contribute nothing (the fact flips false, the actor drops out of the `*By` sets).
|
|
108
|
+
- `binds: commit` — bound to the workspace branch HEAD sha at attest time. A new commit makes it stale. **Lazy convergence:** dashboard payloads and `ls --query` compute facts fresh per request (always honest), but the *persisted* phase regression lands on the next recompute trigger (any CLI verb, watcher event, config change, or boot sweep) — there is no git watcher.
|
|
109
|
+
- `binds: none` — never stale (a standing sign-off).
|
|
110
|
+
|
|
111
|
+
**Validation & teeth.** Declared names are validated by `syntaur doctor` (the `derive-config.valid` check): bad name/type/binds and any collision of an exported field with a built-in or another declaration is reported as an error and the offending declaration is dropped (built-ins always win). A derive condition that references an **undeclared** fact still fails at recompute time (`CompileError`), exactly as before. `syntaur fact set` / `syntaur attest` reject undeclared names, wrong types, and invalid verdicts. Every `fact set` / `attest` is recorded in `statusHistory` with its actor and cause, even when no dimension moves.
|
|
112
|
+
|
|
65
113
|
## Safety notes
|
|
66
114
|
|
|
67
115
|
- **`remove` is destructive.** Without `--force` it refuses if any assignment references the id. Don't suggest `--force` without first running `syntaur status remove <id>` (no force) so the user sees the affected list.
|
|
68
116
|
- **`rename` rewrites many files.** It edits `config.md` AND every affected `assignment.md` in a single atomic transaction (with rollback if any write fails partway). Always run `--dry-run` first on a non-trivial codebase so the user sees the per-file diff.
|
|
69
117
|
- **`terminal: true` is load-bearing.** Terminal statuses affect dashboard progress bars and dependency-satisfaction logic — an assignment with a terminal status counts as "done" for downstream `dependsOn` checks and project-rollup status. Don't toggle this on `pending`-style states without thinking.
|
|
70
|
-
- **`init --force` overwrites a custom block.** Use `reset` first if the user wants a clean slate, OR confirm before passing `--force` if they have unsaved customizations.
|
|
118
|
+
- **`init --force` overwrites a custom block.** Use `reset` first if the user wants a clean slate, OR confirm before passing `--force` if they have unsaved customizations. It resets to the built-in defaults and therefore **drops any `statuses.facts` declarations and `derive` rules** along with the custom statuses — every other `status` subcommand (`set`/`add`/`remove`/`rename`/`reorder`/`transition`) preserves them.
|
|
71
119
|
- **Concurrency.** `rename`'s buffer-write-rollback strategy assumes no concurrent writers. Tell the user to close the dashboard / pause other agents during a rename.
|
|
72
120
|
- **`SYNTAUR_HOME` precedence.** If the user has `SYNTAUR_HOME` set, the CLI writes there instead of `~/.syntaur`. Mirror their environment.
|
|
Binary file
|
|
Binary file
|
|
@@ -62,11 +62,59 @@ After every mutating subcommand, run `syntaur status list` (or `--json` for mach
|
|
|
62
62
|
- **After a `remove --force`,** the affected assignments now reference an undefined status. `syntaur doctor` will flag them as invalid. Suggest the user run `syntaur doctor` and either re-add the status (`syntaur status add ...`) or edit each frontmatter to a valid id.
|
|
63
63
|
- **After `transition add`,** the dashboard's transition buttons reflect the new transition only after the cache invalidation above.
|
|
64
64
|
|
|
65
|
+
## Custom facts and attestations
|
|
66
|
+
|
|
67
|
+
Beyond the 14 built-in derived-status facts, users can declare their **own** facts under `statuses.facts` and reference them in `phaseLadder` / `disposition` conditions. There are two kinds.
|
|
68
|
+
|
|
69
|
+
**1. Custom asserted facts** — config-declared `bool` / `number` values, asserted via `syntaur fact set` and stored in a `facts:` frontmatter map:
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
statuses:
|
|
73
|
+
facts:
|
|
74
|
+
- name: qaPassed
|
|
75
|
+
type: bool
|
|
76
|
+
- name: storyPoints
|
|
77
|
+
type: number
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
syntaur fact set <assignment> qaPassed true --project <p>
|
|
82
|
+
syntaur fact set <assignment> storyPoints 5 --project <p>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`bool` accepts case-insensitive `true`/`false`; `number` accepts any finite number. The declared `name` exports a single derive field of the same name (`qaPassed:true`, `storyPoints > 3`). Stored in frontmatter as `facts:\n qaPassed: "true"`.
|
|
86
|
+
|
|
87
|
+
**2. Attestation facts** — model "agent X reviewed revision Y with verdict Z". Declared with `type: attestation` and a `binds:` mode:
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
statuses:
|
|
91
|
+
facts:
|
|
92
|
+
- name: codeReview
|
|
93
|
+
type: attestation
|
|
94
|
+
binds: plan # plan | commit | none
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
syntaur attest <assignment> codeReview --agent codex --verdict approved --project <p>
|
|
99
|
+
syntaur attest <assignment> codeReview --agent pi --verdict changes-requested --note "fix the lock" --project <p>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`--verdict` defaults to `approved` (the other value is `changes-requested`). One record per actor — re-attesting **replaces** that actor's record. Stored in an `attestations:` frontmatter list (`{fact, actor, verdict, at, note?}` + binding snapshot).
|
|
103
|
+
|
|
104
|
+
Each attestation fact exports **five** derive fields (for `codeReview`): `codeReview` (any valid record), `codeReviewApproved`, `codeReviewChangesRequested` (bools), and `codeReviewBy`, `codeReviewApprovedBy` (actor **sets** — use `:` for contains / `IN`-lists, e.g. `codeReviewApprovedBy:"agent:codex"`; quote actor values that contain a `:`). This makes review loops self-modeling — a rung `when: "codeReviewApproved:true"` fires on approval, and `when: "codeReviewChangesRequested:true"` expresses "reviewed but not signed off".
|
|
105
|
+
|
|
106
|
+
**Revision binding** is what makes attestations self-invalidate:
|
|
107
|
+
- `binds: plan` — bound to the latest plan file + its digest (same semantics as plan approval). A replan or a post-attest plan edit makes the record **stale**; stale records contribute nothing (the fact flips false, the actor drops out of the `*By` sets).
|
|
108
|
+
- `binds: commit` — bound to the workspace branch HEAD sha at attest time. A new commit makes it stale. **Lazy convergence:** dashboard payloads and `ls --query` compute facts fresh per request (always honest), but the *persisted* phase regression lands on the next recompute trigger (any CLI verb, watcher event, config change, or boot sweep) — there is no git watcher.
|
|
109
|
+
- `binds: none` — never stale (a standing sign-off).
|
|
110
|
+
|
|
111
|
+
**Validation & teeth.** Declared names are validated by `syntaur doctor` (the `derive-config.valid` check): bad name/type/binds and any collision of an exported field with a built-in or another declaration is reported as an error and the offending declaration is dropped (built-ins always win). A derive condition that references an **undeclared** fact still fails at recompute time (`CompileError`), exactly as before. `syntaur fact set` / `syntaur attest` reject undeclared names, wrong types, and invalid verdicts. Every `fact set` / `attest` is recorded in `statusHistory` with its actor and cause, even when no dimension moves.
|
|
112
|
+
|
|
65
113
|
## Safety notes
|
|
66
114
|
|
|
67
115
|
- **`remove` is destructive.** Without `--force` it refuses if any assignment references the id. Don't suggest `--force` without first running `syntaur status remove <id>` (no force) so the user sees the affected list.
|
|
68
116
|
- **`rename` rewrites many files.** It edits `config.md` AND every affected `assignment.md` in a single atomic transaction (with rollback if any write fails partway). Always run `--dry-run` first on a non-trivial codebase so the user sees the per-file diff.
|
|
69
117
|
- **`terminal: true` is load-bearing.** Terminal statuses affect dashboard progress bars and dependency-satisfaction logic — an assignment with a terminal status counts as "done" for downstream `dependsOn` checks and project-rollup status. Don't toggle this on `pending`-style states without thinking.
|
|
70
|
-
- **`init --force` overwrites a custom block.** Use `reset` first if the user wants a clean slate, OR confirm before passing `--force` if they have unsaved customizations.
|
|
118
|
+
- **`init --force` overwrites a custom block.** Use `reset` first if the user wants a clean slate, OR confirm before passing `--force` if they have unsaved customizations. It resets to the built-in defaults and therefore **drops any `statuses.facts` declarations and `derive` rules** along with the custom statuses — every other `status` subcommand (`set`/`add`/`remove`/`rename`/`reorder`/`transition`) preserves them.
|
|
71
119
|
- **Concurrency.** `rename`'s buffer-write-rollback strategy assumes no concurrent writers. Tell the user to close the dashboard / pause other agents during a rename.
|
|
72
120
|
- **`SYNTAUR_HOME` precedence.** If the user has `SYNTAUR_HOME` set, the CLI writes there instead of `~/.syntaur`. Mirror their environment.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{aq as o,ar as n}from"./mermaid.core-eqq1_dL_.js";const t=(r,a)=>o.lang.round(n.parse(r)[a]);export{t as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-WL4C6EOR-DV11wZKH.js";import{_ as i}from"./mermaid.core-eqq1_dL_.js";import"./chunk-FMBD7UC4-CWHswGwW.js";import"./chunk-JSJVCQXG-DnsqdfIB.js";import"./chunk-55IACEB6-DE34igmQ.js";import"./chunk-KX2RTZJC-FbqVE08c.js";import"./index-Dzh96P4Z.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-WL4C6EOR-DV11wZKH.js";import{_ as i}from"./mermaid.core-eqq1_dL_.js";import"./chunk-FMBD7UC4-CWHswGwW.js";import"./chunk-JSJVCQXG-DnsqdfIB.js";import"./chunk-55IACEB6-DE34igmQ.js";import"./chunk-KX2RTZJC-FbqVE08c.js";import"./index-Dzh96P4Z.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as r}from"./_baseUniq-DGO4Y46J.js";var e=4;function a(o){return r(o,e)}export{a as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as e,b as r,a,S as s}from"./chunk-NQ4KR5QH-DcsdDqWQ.js";import{_ as i}from"./mermaid.core-eqq1_dL_.js";import"./chunk-55IACEB6-DE34igmQ.js";import"./chunk-KX2RTZJC-FbqVE08c.js";import"./index-Dzh96P4Z.js";var p={parser:a,get db(){return new s(2)},renderer:r,styles:e,init:i(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")};export{p as diagram};
|