feat(org): intake — route work before anything is written - #269
Conversation
The substrate is a bet: that a session leaves something the next one can inherit. Nothing measured it. `org sweep` does, from the chains alone, with no cooperation from any agent. It REPLAYS each chain through the kernel rather than scanning kinds, because the number that matters is invisible to a scan: a takeover's record does not name the claim it stranded, so an orphaned obligation is only visible as a fold transition. The sweep counts orphans, and how many a successor then discharged. The headline pair: distilled session ends (a checkpoint — a real conclusion) against ones only observed (a mark), and inherited obligations discharged against orphaned. A rate with no data renders as an em dash, never 0% — "no session has ended yet" and "every session ended undistilled" are the two findings that must never share a value. A chain that stops folding is a BROKEN row carrying the counts from before the break, not a failed sweep. Exposed over MCP as org_sweep (read-only, so it joins the allowlist). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…see it Two related findings from review round 1, both about the same gap: the sweep claimed to preserve what a chain recorded before a break, and neither path actually delivered it. survey.Of returned early on a refused record without carrying the state that DID fold, so a BROKEN row reported no dangling work and Sum's counter undercounted — a chain could strand an obligation and the aggregate would say zero. Both exits now go through one withState, so the broken and healthy paths cannot report different fields. cmdSweep read through Load, which folds internally and is all-or-nothing: a chain that stopped folding arrived empty, so the CLI reported zero records for exactly the chain worth looking at. It now reads records via the new home.Records and lets the replay decide admissibility. Tests pin both, plus the revoke-while-active orphan path the review flagged as untested — revoke reaches the same kernel orphan() as takeover through a different transition, and "high confidence by inspection" is how the untested arm of a pair diverges. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Round-2 finding: LastAt was stamped from the tip after the loop, so the early return on a refused record left it empty — a BROKEN row exists to be diagnosed from, and a reader cannot diagnose a chain that will not say when it was last valid. It is now stamped per folded record, which is the only place it can come from: state carries no timestamp, so withState cannot recover it afterwards. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…g is written The first live multi-lane run's headline gap (field report §4.1): two agents, one hour, zero work registered — every minute spent discovering routing facts the substrate could have answered. org intake answers them read-only: which chartered lanes' scopes cover a work URI, which lanes already hold it (an out-of-scope hold renders as drift, §4.4's proven gap), and when nothing covers it, that fact plus the fix. The membership predicate the skills already claimed — 'a mechanical predicate, never a judgment call' — now exists: contracts/org.InScope, prefix-at-a-boundary, never across schemes (§4.5's rule), with explicit open-prefix entries (jira:PROJ-, github:owner/, jira:) stating a charter's grain. assign can enforce it later; intake reads it today. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Claude finished @itsHabib's task in 5m 0s —— View job PR #269 Review —
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 802b9e1f04
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if in.Covered { | ||
| return sb.String() | ||
| } | ||
| fmt.Fprintf(&sb, "no chartered scope covers %s\n", in.Work) | ||
| sb.WriteString("fix: charter a lane whose -scope covers it, or recharter an existing lane\n") |
There was a problem hiding this comment.
Handle unreadable lanes before declaring no coverage
When a role directory contains a corrupt or unreadable chain and no readable lane matches, intakeLane retains the error row but leaves Covered false, so this renderer definitively says that no chartered scope covers the work and recommends creating or rechartering a lane. The unreadable chain may be the covering owner, so following that advice can create a competing lane; represent the result as indeterminate and suppress the no-coverage conclusion until every lane has been judged.
AGENTS.md reference: cmd/org/AGENTS.md:L33-L38
Useful? React with 👍 / 👎.
| // `github:owner/repository`. An entry that itself ends in a separator is an | ||
| // explicit open prefix — `jira:PROJ-` covers a project, `github:owner/` an | ||
| // owner, `jira:` a whole scheme — which is how a charter states its grain |
There was a problem hiding this comment.
Make advertised scheme-wide scopes charterable
The advertised jira: whole-scheme scope cannot be used by org intake: the existing workURIPattern in contracts/org/validate.go requires at least one non-whitespace character after the colon, and the JSON schema has the same restriction, so org charter -scope jira: is refused as malformed. Align charter/schema validation with this newly supported open-prefix form, or remove the unreachable scheme-wide behavior and documentation.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Reviewed head: 802b9e1
InScope predicate — contracts/org/scope.go
The implementation is correct on both §4.4 and §4.5.
§4.5 (never cross schemes): Enforced structurally by strings.HasPrefix. Any entry whose scheme prefix differs from the work URI's scheme prefix fails the prefix check at the first byte divergence. No explicit scheme guard is needed and none would add safety. ✓
§4.4 (drift surfaced, not silenced): intakeLane in cmd/org/main.go:541 calls MatchScope and then separately scans state.Held. A lane that holds the work but whose scope doesn't match it returns ScopeMatch="" + Holds=true — the keep=true path — and laneNote renders it as "holds it OUT OF SCOPE". The field-report failure mode (silent acceptance into a mismatched lane) becomes a visible row in the report. ✓
The openPrefix / boundary asymmetry (contracts/org/scope.go:26-32) is correct and load-bearing: '-' appears in openPrefix (so jira:PROJ- is an explicit open prefix) but NOT in boundary (so github:owner/my does not cover github:owner/my-repo — the character after the entry is '-', which fails the boundary check). The test at scope_test.go:17 ({"github:owner/my", "github:owner/my-repo", false}) pins this. ✓
P2 — Missing # open-prefix test in scope_test.go:
The four open-prefix characters are '/', '#', ':', '-'. Tests cover entries ending in '/' ("github:owner/"), ':' ("jira:"), and '-' ("jira:PROJ-"), but not '#'. A case like:
{"github:owner/repo#", "github:owner/repo#88", true},
{"github:owner/repo#", "github:owner/repo/path", false},would complete the coverage for all four open-prefix characters. The logic is identical to the / path, so this is a coverage gap rather than a bug, but the field report §4.4 specifically names # as a structural boundary character that must work correctly. Fix this →
P3 — JSON output for unreadable chains has "phase": "":
When h.Load fails inside intakeLane (main.go:543), lane.Phase stays as the zero value (""), which is PhaseVoid. The "error" field signals the condition, but a machine consumer inspecting "phase" sees "" (void) rather than something that indicates "unknown due to read error." The Err field is the correct signal — this is a documentation clarity gap, not a bug — but adding omitempty to Phase in IntakeLane (render/intake.go:15) would make the signal unambiguous: a missing phase key means the chain was unreadable.
P3 — PhaseVoid exclusion is implicit rather than guarded:
intakeLane (main.go:549) explicitly guards PhaseRetired. Void chains are correctly excluded too — MatchScope(nil, work) returns ("", false) and empty held list yields keep=false — but this relies on emergent behavior rather than an explicit check. A one-line guard if state.Phase == org.PhaseVoid { return lane, false } (or a comment) would make the intent legible to a future reader of the phase-filtering logic.
Read-only guarantee — cmdIntake
cmdIntake (main.go:507-537) calls h.RolesForTenant and, inside intakeLane, h.Load only. Neither call is a write path. h.Append is never invoked. The lock acquired by home.Open is not held in read-only callers — s.open(args, false) confirms no role is required and no write is attempted.
Exit code is always 0 on a successful report, regardless of whether any lane covers the URI (in.Covered is a field in the output, not an exit signal). This makes intake safe as a reflex — exit 0 is the invariant. The test at main_test.go:378 confirms it. ✓
P3 — newScope adds unused flags to intake:
cmdIntake calls newScope("intake"), which registers -incarnation, -strict, -role, and -json flags. The -json flag is consumed. The others are accepted but have no effect (no write path, no role-scoping). A user who passes -role lead:foo would get the full-tenant report, not a narrowed one. This is not a bug but could surprise a caller. A usage note or explicit rejection of -role for intake would be cleaner, though the current behavior is safe.
Guide-pair sync
cmd/org/CLAUDE.md and cmd/org/AGENTS.md carry the same blob SHA (ba6304122ed166f8838b27c7e5389ac503db23e2) in the changed-files listing, and diff cmd/org/CLAUDE.md cmd/org/AGENTS.md returns empty. Byte-identical. Both include the intake verb description and read-only characterization. CI's guide-pair sync requirement is satisfied. ✓
The intake entry in both guides ("Read-only; safe to run on sight of new work") matches the implementation's exit-0 contract.
Summary
No P1 issues found. The InScope predicate correctly enforces both §4.4 drift-surfacing and §4.5 cross-scheme exclusion. The read-only guarantee holds at the call-site level. Guide-pair is byte-identical.
Residual items: one P2 (missing # open-prefix test covering all four boundary characters), two P3s (JSON phase zero-value for error lanes; implicit PhaseVoid exclusion). None of these block the merge — the first is the most worth closing before assign enforces this predicate in the next slate item.
…unreadable lanes
- contracts/org: scope entries validate against scopeEntryPattern (the
remainder optional) so the advertised bare-scheme grain (jira:) is
actually charterable; Subject work URIs keep the strict pattern.
- intake render: an uncovered report with unreadable lanes hedges ('no
READABLE chartered scope … N lane(s) unreadable') instead of concluding
nothing covers the work; phase omits from JSON when a chain was
unreadable; PhaseVoid excluded explicitly.
- tests: all four open-prefix boundary chars, bare-scheme charter
end-to-end, and the unreadable-lane hedge.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review Round-1 fold pinned to |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5c091758b8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| for i, s := range r.Terms.Scope { | ||
| if !workURIPattern.MatchString(s) { | ||
| if !scopeEntryPattern.MatchString(s) { |
There was a problem hiding this comment.
Align the schema with bare-scheme scope admission
The fresh folded tree changes Go admission to accept jira:, but contracts/org/schema/org-record-v1.json line 59 still requires \S+ after the colon. Consequently, a charter emitted successfully by this CLI is invalid according to the embedded schema consumed by non-Go implementations. Update the scope item's schema pattern—and add it to the pattern conformance test—so both contract representations accept the advertised scheme-wide scope.
AGENTS.md reference: AGENTS.md:L19-L22
Useful? React with 👍 / 👎.
| if *work == "" { | ||
| return fmt.Errorf("-work is required") |
There was a problem hiding this comment.
Reject malformed intake work URIs
When a scheme-wide scope exists, inputs such as org intake -work 'jira: bad' pass this nonempty-only check and are reported as covered because InScope("jira:", ...) accepts every matching prefix, even though assign later refuses the same value under workURIPattern. Validate -work with the subject-work grammar before routing so intake cannot recommend a lane for work that the system cannot record.
AGENTS.md reference: cmd/org/AGENTS.md:L33-L38
Useful? React with 👍 / 👎.
…uses unrecordable URIs - contracts/org/schema: the scope item pattern gains the optional remainder, matching Go admission; the pattern conformance test now covers the scope grammar so the two representations cannot drift again. - intake validates -work against the subject-work grammar (exported as org.ValidWorkURI) before routing — it never recommends a lane for work the kernel could not record. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review Round-2 fold pinned to |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e18a0b6d05
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| {"scope", s.child(t, "terms").child(t, "scope").Items.Pattern, | ||
| []string{"github:acme/api", "jira:PROJ-", "jira:"}, | ||
| []string{"PROJ-412", "jira: bad", ""}}, |
There was a problem hiding this comment.
Exercise the schema regex in the conformance test
The new scope case reads tc.pattern but uses it only in failure messages; both loops execute only the Go matcher returned by goPattern. Consequently, changing the schema back from \S* to \S+—or to any unrelated pattern—leaves this test green while Go and non-Go consumers disagree about whether jira: is valid. Compile and execute the schema pattern against the same cases, then compare its result with Go admission.
AGENTS.md reference: AGENTS.md:L19-L22
Useful? React with 👍 / 👎.
| type Intake struct { | ||
| Work string `json:"work"` | ||
| Tenant string `json:"tenant"` | ||
| Covered bool `json:"covered"` |
There was a problem hiding this comment.
Represent unreadable intake results as indeterminate in JSON
When every readable lane misses but one chain is unreadable, -json still emits "covered": false. Fresh evidence in this fold is that the JSON branch returns this struct before IntakeText, so the new human-readable hedge never reaches machine callers. A caller routing on covered can therefore interpret an unjudged result as confirmed uncovered and charter a competing lane; make coverage tri-state or expose an explicit completeness/indeterminate field.
AGENTS.md reference: cmd/org/AGENTS.md:L33-L38
Useful? React with 👍 / 👎.
|
Round cap reached — recording the final round's two P2s as deferrals for the judge rather than a fourth panel round:
Both are queued for the transfer/scope_mismatch slate PR. |
|
@claude please review this PR and publish your findings as a FORMAL GitHub review pinned to head e18a0b6f0c25514ca29632086463aabb42a94dd0 — not only a comment. The two known residual P2s are recorded as deferrals in the comment above; verify the round-2 fixes (schema/Go scope-pattern agreement + conformance coverage, intake's ValidWorkURI guard) and flag anything new at P1. |
|
Claude finished @itsHabib's task in 3m 53s —— View job PR #269 Review — Round-2 fold verificationReviewed head:
Formal review posted. Summary: Fix 1 verified — schema/Go scope-pattern agreement:
Fix 2 verified —
New P1 scan: nothing found. Read-only guarantee intact; Known deferred P2s: both accurately described and as-recorded. No new findings at P1 or above. |
There was a problem hiding this comment.
Reviewed head: e18a0b6f0c25514ca29632086463aabb42a94dd0
Round-2 fold — verification of the two fixes
Fix 1: Schema/Go scope-pattern agreement + conformance coverage
Go side (contracts/org/validate.go:30):
scopeEntryPattern = regexp.MustCompile(`^[a-z][a-z0-9+.-]*:\S*$`)Uses \S* — bare-scheme entries (jira:) are admitted. ✓
Schema side (contracts/org/schema/org-record-v1.json:59):
"pattern": "^[a-z][a-z0-9+.-]*:\\S*$"Also \S*. The two representations agree character-for-character. ✓
Conformance test (contracts/org/conformance_test.go:144–146):
{"scope", s.child(t, "terms").child(t, "scope").Items.Pattern,
[]string{"github:acme/api", "jira:PROJ-", "jira:"},
[]string{"PROJ-412", "jira: bad", ""}},goPattern(t, "scope") returns scopeEntryPattern.MatchString (validate.go:176). The accept list exercises the bare-scheme case; the reject list gates spaces and empty strings. If Go drifts back to \S+, the "jira:" accept case fails. If Go begins accepting "jira: bad", the reject case fails. Indirect but effective guard against Go regression. ✓
The known deferred P2 stands: the schema pattern string is loaded from the JSON but not compiled and executed as a regex — tc.pattern appears only in error messages. A schema revert to \S+ would leave this test green while non-Go consumers disagree. Deferred as recorded; agreed it's a harness-wide change.
Fix 2: Intake's ValidWorkURI guard
cmdIntake (cmd/org/main.go:517–519):
if !org.ValidWorkURI(*work) {
return fmt.Errorf("-work %q is not a valid work URI (scheme:reference); the kernel could never record it", *work)
}workURIPattern requires \S+ (one or more non-whitespace after the colon), so bare-scheme values (jira:) and values with embedded spaces (jira: bad) are refused before routing. The test at main_test.go:418–420 pins both the exit code (codeError) and the error text ("not a valid work URI"). Guard is in place and covered. ✓
New P1 scan — none found
Read-only guarantee: cmdIntake calls s.open(args, false), h.RolesForTenant, and h.Load only. h.Append is unreachable from this code path. Exit 0 on all successful report paths; the ValidWorkURI refusal exits via return error (non-zero), which is correct — it is a usage error, not a report. ✓
intakeLane phase guards (main.go:552): the explicit PhaseVoid || PhaseRetired guard added in round-1 is intact. Void/retired lanes are dropped (keep=false) before MatchScope is called, so no zero-value scope-match leaks into the report. ✓
InScope predicate: unchanged from round-1 verification. Cross-scheme exclusion and open-prefix/boundary asymmetry remain correct. ✓
Scope test — # coverage: scope_test.go:25–26 now has:
{"github:owner/repo#", "github:owner/repo#88", true},
{"github:owner/repo#", "github:other/repo#88", false},All four open-prefix characters (/, #, :, -) are covered. The P2 from round-1 is closed. ✓
Unreadable-lane hedge in text (render/intake.go:45–48): unreadable(in.Lanes) is checked before emitting the no-coverage conclusion; text report hedges correctly when any lane was unreadable. ✓
Phase field with omitempty (render/intake.go:16): unreadable lanes never set lane.Phase, so the field is absent from JSON output rather than zero-valued. P3 from round-1 is closed. ✓
Known deferred P2s — acknowledged, no action expected
- Conformance test does not execute the schema regex (
contracts/org/conformance_test.go): recorded in the PR comment; fix scoped to a harness-wide change across all four grammar cases on the next slate PR. - JSON
coveredis binary when unreadable lanes exist (render/intake.go:31): text hedges; JSON does not carry anindeterminatemarker. Recorded; additive field queued alongsidescope_mismatchwork.
Both P2s verified as accurately described. No new findings at P1 or above.
# Conflicts: # cmd/org/AGENTS.md # cmd/org/CLAUDE.md # cmd/org/main.go # cmd/org/main_test.go
|
@claude please review this PR and publish your findings as a FORMAL GitHub review pinned to head 4d54a91 — not only a comment. This head is the fully-reviewed e18a0b6 content plus a mechanical merge of main (the #265/#266 squashes); the conflict resolution took the branch's own files verbatim. Verify the merge introduced nothing new; the two recorded P2 deferrals stand. |
|
@codex review |
|
Claude finished @itsHabib's task in 2m 15s —— View job PR #269 Review — Merge-head verification (
|
| Finding | Status |
|---|---|
InScope cross-scheme exclusion (§4.5) via strings.HasPrefix |
✓ intact |
Drift surfacing (§4.4) — "holds it OUT OF SCOPE" path in intakeLane |
✓ intact |
ValidWorkURI guard (main.go:517–519) |
✓ intact, tested |
Schema/Go \S* pattern agreement |
✓ intact |
# open-prefix coverage in scope_test.go |
✓ intact |
Read-only guarantee — h.Append unreachable, exit 0 on all report paths |
✓ intact |
omitempty on Phase in render/intake.go:16 |
✓ intact |
Explicit PhaseVoid || PhaseRetired guard (main.go:552) |
✓ intact |
Known deferred P2s — unchanged, accurately recorded
-
Conformance test does not execute the schema regex (
contracts/org/conformance_test.go):tc.patternis loaded but used only in error messages; only the Go matcher runs. A schema revert to\S+would leave this test green while non-Go consumers diverge. Deferred to the next slate PR as a harness-wide change across all four grammars. -
JSON
coveredis binary when unreadable lanes exist (render/intake.go:31): text output hedges;-jsonstill emits"covered": falsefor an unjudged result. Deferred alongside thescope_mismatchwork that will consume this field.
Both P2s are accurately described in the recorded deferrals. No new findings at P1 or above. The merge introduced nothing beyond the #265 sweep squash from main, and that squash's changes to the four conflicted files were fully overwritten by the branch's own content.
There was a problem hiding this comment.
Reviewed head: 4d54a91
Merge verification
This head is the previously-reviewed e18a0b6 content plus a mechanical merge of origin/main (the #265 sweep squash). The merge commit records four conflict files:
# Conflicts:
# cmd/org/AGENTS.md
# cmd/org/CLAUDE.md
# cmd/org/main.go
# cmd/org/main_test.go
Claim verified: git diff e18a0b6..HEAD -- cmd/org/AGENTS.md cmd/org/CLAUDE.md cmd/org/main.go cmd/org/main_test.go returns empty. The conflict resolution took the branch's own files verbatim for all four contested paths. No functional change was introduced to any file owned by this PR.
contracts/ unchanged: git diff e18a0b6..HEAD -- contracts/ also returns empty. The InScope predicate, scope validation, schema, and tests are identical to the round-2 reviewed state. ✓
Full PR stat vs main matches the PR metadata exactly:
11 files changed, 388 insertions(+), 5 deletions(-)
No files added or removed by the merge beyond what was already in the branch. ✓
Guide-pair sync at new head
diff cmd/org/CLAUDE.md cmd/org/AGENTS.md → empty. Byte-identical. The merge did not skew the pair — both files took the branch's version of the intake verb entry verbatim. ✓
Round-2 verified findings — still hold
All findings confirmed at e18a0b6 remain in place:
InScopecross-scheme exclusion (§4.5): structurally enforced bystrings.HasPrefix. ✓- Drift surfacing (§4.4):
holds it OUT OF SCOPEpath intact inintakeLane. ✓ ValidWorkURIguard (main.go:517–519): intact, tested. ✓- Schema/Go
\S*pattern agreement: intact. ✓ #open-prefix coverage inscope_test.go: intact. ✓- Read-only guarantee:
h.Appendunreachable fromcmdIntake. Exit 0 on all report paths. ✓ omitemptyonPhaseinrender/intake.go:16: intact. ✓- Explicit
PhaseVoid || PhaseRetiredguard (main.go:552): intact. ✓
Known deferred P2s — unchanged, accurately recorded
-
Conformance test does not execute the schema regex (
contracts/org/conformance_test.go):tc.patternis loaded but used only in error messages; only the Go matcher runs against the test cases. A schema revert to\S+would leave this test green while non-Go consumers diverge. Deferred to the next slate PR as a harness-wide change across all four grammars. -
JSON
coveredis binary when unreadable lanes exist (render/intake.go:31): text output hedges;-jsonstill emits"covered": falsefor an unjudged result. Deferred alongside thescope_mismatchwork that will consume this field.
Both P2s are accurately described in the recorded deferrals. No new findings at P1 or above. The merge introduced nothing beyond the #265 sweep squash from main, and that squash's changes to the four conflicted files were fully overwritten by the branch's own content.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4d54a912bb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // charter's scope entry is a prefix, not a work item, and a bare scheme | ||
| // (`jira:`) is the widest legal grain a lane can state (see scope.go's | ||
| // open-prefix rule). Subject work URIs never get this latitude. | ||
| scopeEntryPattern = regexp.MustCompile(`^[a-z][a-z0-9+.-]*:\S*$`) |
There was a problem hiding this comment.
Version bare-scheme scopes before writing them
When a new client charters -scope jira:, this broadened validator still emits a version-1 chain with min_reader: 1, but any pre-change version-1 reader retains the old \S+ grammar and rejects the genesis record as malformed_work_uri. In a mixed deployment, introducing the advertised scheme-wide scope therefore makes the role inaccessible to older clients despite the record claiming version-1 compatibility; either use a representation accepted by existing v1 readers or advance the record/reader version for this grammar expansion.
Useful? React with 👍 / 👎.
…er/annul (#272) * feat(org): scope drift, deadlines that die with their tenure, recharter/annul Four slate items and the four P2 deferrals recorded on #269/#270. - sweep reports scope_drift: work a role holds outside its own charter scope, judged by contracts/org.InScope. It is a FINDING, not a refusal — Reduce replays every historical record through Admissible, so a scope law added today would refuse chains that folded yesterday, and the opt-in charter term that would scope it changes every historical digest because Terms.Canonical emits every field. FOLLOWUPS records what a real fix costs (a canon/v2 scheme), so the next session does not re-derive it. - next_due dies with the tenure: release, revoke, retire and takeover keep only what their own record declares. A released lane was 'late' forever against a deadline nobody owned — the supervisor skill carries a written workaround for exactly this, which can now go. - recharter and annul get CLI verbs; both kinds were kernel-admissible with no way to write them. recharter prints the terms it REPLACES (it is not a patch); annul defaults -target to the tip, the only thing a fold can verify. - Deferrals closed: begin preflights claim blockers before writing anything; done discharges a dangling claim by completing it rather than re-claiming it (and doneTarget resolves to it); the schema-pattern conformance test now compiles and runs the schema's own regex — mutation-checked by reverting the scope pattern, which the test catches; intake's JSON carries indeterminate + unreadable_lanes so covered:false is not read as proof. - sweep's attention line is composed from findings that actually fired, so a zero count is never rendered. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: fold round 1 — withdraw recharter, make annul tell the truth Both P1s were on verbs this PR newly exposed, and both are real. - recharter is WITHDRAWN, not patched. A holder could recharter itself to a higher tier, more effect classes, bigger ceilings, or fewer supervisors, all self-signed: checkRecharter verifies only min_reader monotonicity and checkWriter accepts the holder's own incarnation. The guard that would fix it cannot be written either — Tier is an opaque string, so the kernel has no ordering to tell attenuation from escalation. FOLLOWUPS records what parent authority would take; until then terms are set once at charter and a wrong role is retired and re-chartered, visibly. - annul no longer claims to withdraw anything. The fold appends the digest to Annulled and leaves Terms/Held/Active/NextDue standing, so the verb now prints the effect that survives and the verb that would undo it, and the guides say repudiation rather than withdrawal. Whether a fold should SKIP annulled records is a two-pass question filed in FOLLOWUPS, not smuggled in here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: fold round 2 — min_reader floor, annul wording in top-level help Both P2s from the final panel round; the first is a regression this PR introduced with the -min-reader flag. - checkCharter refuses a negative min_reader. The schema has declared minimum 0 all along and the Go side did not, so -min-reader=-1 wrote a record this kernel accepted and every other reader of the contract must reject. Replay assessment, the same one this PR's FOLLOWUPS entry demands: min_reader had no writer that could set it before this PR (every charter hardcoded 1), so the law refuses no existing chain. - The top-level usage line said annul withdraws the tip. It repudiates it. The verb doc, guides and README already said so; the help did not. Round cap reached: no further panel rounds, residuals to the judge. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Summary
Closes the field report's headline gap (§4.1): there was no intake path — two agents spent an hour registering zero work.
org intake -work <uri>answers, read-only, which chartered lanes could hold a work URI and precisely what is missing if none can.What this adds
contracts/org.InScope/MatchScope— the scope-membership predicate the skills already claimed existed ("a mechanical predicate, never a judgment call") but the kernel never enforced (§4.4, proven twice). Prefix-at-a-boundary; never across schemes (§4.5's rule); explicit open-prefix entries (jira:PROJ-,github:owner/,jira:) state a charter's grain without glob syntax. A pure leaf function: intake reads it today,assigncan enforce it later (scope_mismatchis the next slate item).org intake -work <uri> [-json]— for each live lane in the tenant: in scope (which entry), already holds it (an out-of-scope hold renders as "holds it OUT OF SCOPE" — §4.4's drift, surfaced instead of silent), unreadable chains named rather than skipped. When nothing covers the URI: the fact plus the fix (charter or recharter). Exit 0 — it is a report; safe to make the reflex.Validation
Stacked on #266 (shares cmd/org/main.go); retarget to its base when the train advances.
🤖 Generated with Claude Code