Maintainer decision, 2026-07-29: adopts TRSL V1C1 as this repo's
preliminary governing license, per target-revenue's
workplans/TREV-WP-0008-governance-and-pilot-rollout.md T05. Full
specialist legal review is deferred until out of beta (target-revenue
SCOPE.md §1). No Phase is yet declared for this repo.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add Intake Definition of Comprehension and work-item Definition of Ready as
hub policies with dashboard edit surfaces, document the Definition family and
DoX-Ok/Failed badge convention, and mark STATE-WP-0076 finished.
Align dashboard reference pages with intake-as-discovery and suggestions as
legacy, frame work records as unit vs structure artefacts, and add the ready
STATE-WP-0076 plan for DoC/DoR quality policies. Include generated work-record
index and recent legacy-meter evidence captures.
Default domain was retired slug "custodian", so POST /technical-debt/
returned 422 and the modal failed after open. Use infotech, resolve
apiBase like config.js, and surface API error detail in the toast.
Founder-reviewed decision (WorkOrchestrationArchitectureDraft.md v0.2
section 8 item 6): the fresh intake work-record entity replaces
suggestions, not a rename-bridge. All 5 mutation endpoints (create, vet,
decline, promote, bump-relevance) now 410 with a pointer to POST
/intakes/ and the migration doc; GET/list stay live for the historical
record (10 rows migrated to file-backed intake records in the-custodian,
see that repo's intake-legacy-suggestions-migration.md and CUST-IN-0001
through CUST-IN-0010).
Removed dead code the retirement makes unreachable: Task/TaskPriority/
TaskStatus/normalize_task_status imports (only used by the deleted
promote body), the suggestion_relevance.bump_relevance import, and the
_ALLOWED_*_FROM stage-guard sets + _reject_stage helper (only used by
the deleted vet/decline/promote bodies). WSJF ranking (compute_wsjf,
cost_of_delay, suggestion_sort_key) stays -- still exercised by the
surviving GET /suggestions/?rank=wsjf read path.
MCP tool docstrings (create_suggestion, vet_suggestion,
decline_suggestion, promote_suggestion_to_task,
bump_suggestion_relevance) updated to point at the replacement
(create_intake/route_intake/close_intake) rather than silently 410ing
with no guidance.
tests/test_suggestions.py rewritten: verifies all 5 mutations 410,
GET/list still work for historical rows (seeded directly via the DB
session since creation is retired -- there's no other way to get
historical data into the table anymore), 404 still behaves normally on
unknown ids. Live-verified against the running dev API: POST 410s,
GET with include_terminal=true still returns all 10 migrated-and-declined
historical rows. No regressions: full repo suite green (563 tests).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
First cut of the transclusion-style index named in the stage-3 seed: a
WORK-RECORDS.md at repo root listing kind/id/status/lane/source for
every workplan, task, intake, decision, and engagement found in the
repo -- derived purely from files (no hub query), matching the ADR-001
rebuild principle. Full markitect transclusion rendering is a
follow-on, not this first cut.
- _generate_work_record_index(): reuses iter_workplan_files/
parse_frontmatter/get_tasks_from_workplan for workplan+task rows,
and the repo-wide yaml-block scan already proven by C-31/C-32 for
intake/decision/engagement rows. Archived workplans excluded (index
is for current orientation, not history); closed decisions/intakes/
engagements stay listed. Returns None (no file written) for repos
with zero work records, to avoid clutter.
- _check_work_record_index_freshness(): C-33, WARN+fixable when
WORK-RECORDS.md is missing or its content differs from a fresh
regeneration.
- fix_repo C-33 dispatch: overwrites the file with the regenerated
content.
13 new tests (generation across all kinds, sort order, archived
exclusion, self-scan exclusion, freshness detection incl. idempotence).
No regressions: full repo suite green (561 tests).
Live-verified at two scales: binky-control (5 workplans, 31 tasks, 3
intake, 4 decisions, 5 engagements) and the-custodian (52 workplans,
332 tasks) -- both generated correctly on first run, confirmed
idempotent (identical second run produces no C-33 fix), and the larger
repo's scan added no material overhead to the existing ~1.5min
fix-consistency run.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The mechanism named in canon/standards/work-record-types_v0.1.md:
"Promotion is a first-class transition... manual transcription of an
intake item into other kinds is a process defect." This is what AWQ-010
needed and didn't have -- a human/agent had to notice, transcribe, and
re-register it by hand. One call now does what that manual pass did.
scripts/promote_intake.py: intake.routed -> workplan | task | decision |
engagement.
- workplan: new ADR-001 file at workplans/{ID}-{slug}.md, registered
against the hub (repo+topic resolution, POST /workplans, frontmatter
id write-back)
- task: appended as a ```task``` block to an existing --workplan-file,
registered via POST /tasks, reuses the existing
_inject_task_id_into_block writeback helper
- decision: appended as a ```yaml``` block with a fresh
{PREFIX}-DEC-{YYYY}-{NNN} id to --target-file, registered the same
way C-32 registers decisions (reuses _inject_yaml_block_field)
- engagement: appended as a ```yaml``` block with a fresh
{PREFIX}-ENG-{YYYY}-{NNN} id -- file-only, no hub entity exists yet
(same honest deferral as C-32), reported not silently skipped
In every case the intake is closed with outcome=promoted and
promoted_to=<new canonical id>; the new record carries an
origin: "intake:<id>" back-link.
Wired as `statehub promote-intake <intake-id> --to <kind> --repo-slug
<slug> --repo-path <path> --domain <domain> [--target-file ...]
[--workplan-file ...]`, matching the CLI shape named in the workplan text.
17 tests: pure helpers (_slugify, _next_number, _append_yaml_block,
frontmatter injection) offline; full promote_intake() flow with the hub
API mocked.
Live-verified against the real running API/DB and a real repo
(binky-control), not just mocks -- and the live proof caught a real bug:
the first workplan-promotion run silently produced a false success (the
intake was closed outcome=promoted, but /workplans/ actually 422'd on a
missing repo_id that the code never resolved, so no workstream was ever
created). Fixed to resolve repo_id via /repos/{slug} and to raise loudly
on registration failure instead of writing a half-registered file
silently; locked in as two regression tests. Re-verified clean:
workplan promotion (CLI direct + through `statehub promote-intake`
itself) and decision promotion both proven end-to-end against the live
hub, with all scratch artefacts (files + hub rows) cleaned up afterward.
No regressions: full state-hub suite (271 tests across
test_promote_intake, test_intake, test_work_record_registration,
test_work_record_check, test_routers_core, test_consistency_check,
test_consistency_sweep, test_mcp_smoke, test_mcp_write_tools) green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extends fix-consistency to scan any file for kind: intake / kind: decision
YAML blocks (not just workplans/, per canon: any file is a potential
work-record source), create the corresponding hub entity when missing a
state_hub_intake_id / state_hub_decision_id, and write the id back into
the source block -- same write-back pattern as C-06 for workplans.
kind: engagement is reported INFO (deferred, not fixable): no hub entity
exists for it yet, a separate stage-3 follow-on.
- _load_work_record_kind_registry(): kind-aware registry loader, factored
out so C-31's existing flat _load_work_record_patterns() builds on it
without duplication (verified: C-31's 16 tests still pass unmodified)
- _check_work_record_registration(): detection, wired into check_repo
right after C-31
- _inject_yaml_block_field(): write-back helper for fenced
blocks, mirroring _inject_task_id_into_block's pattern for
blocks
- fix_repo C-32 dispatch: creates the intake (scoped to repo_id) or
decision (scoped to resolved topic_id, reusing C-06's domain->topic
resolution) via the REST API, then writes the id back
- tests/test_work_record_registration.py: 15 tests (classification,
detection incl. engagement-deferred and workplan-kind-exclusion,
injection incl. idempotence and non-interference with sibling blocks)
Live-verified end to end against a real registered repo (binky-control,
not just synthetic fixtures): a real fix-consistency run found and
registered 3 genuinely open, previously-unlinked intake items
(AWQ-002/003/006) sitting in AutopilotWorkQueue.md, and correctly
deferred 5 real OH- engagement items as INFO. No regressions: full
consistency_check + consistency_sweep suite (128 tests) and C-31's own
suite (16 tests) still green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fresh hub entity per the founder-reviewed decision (not a suggestions
rename-bridge): kind: intake per canon/standards/work-record-types_v0.1.md,
lifecycle open -> vetted -> routed -> closed(promoted|declined|absorbed).
- api/models/base.py::new_uuid7 -- dependency-free RFC 9562 UUIDv7
generator (48-bit ms timestamp, version/variant bits, random remainder);
existing tables keep new_uuid (UUIDv4) unchanged, this is opt-in for new
work-record entities per the identity-layering canon
- api/models/intake.py: Intake + IntakeNote ORM models, mirroring
Decision's shape (topic/workplan/repo scope, lane, status, outcome,
promoted_to back-link); CHECK constraints enforce scope-required,
closed-requires-outcome, promoted-requires-promoted_to at the DB level
- migrations/a7c3e9f1b4d2: intakes + intake_notes tables, 3 enum types
- api/routers/intake.py: list/create/get/patch + /route + /close + /notes
actions, mirroring decisions.py's pattern (409 on invalid transitions,
progress event on close)
- api/schemas/intake.py: Pydantic create/update/route/close/note schemas
- mcp_server/server.py: create_intake, list_intakes, route_intake,
close_intake tool wrappers
- tests/test_intake.py: 12 tests against the real Postgres test DB
(create/list/scope-validation, full lifecycle incl. 409s and the
promoted-requires-promoted_to constraint, notes, UUIDv7 verification)
Verified live against the running dev API + DB (not just pytest): applied
the migration, restarted the MCP server, and ran a full create -> route ->
close cycle over the real REST endpoints. No regressions: full existing
suite (test_routers_core, test_suggestions, test_mcp_smoke,
test_mcp_write_tools, test_mcp_registration, test_consistency_check,
test_consistency_sweep) all green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
16 tests: registry loading (env override, missing registry, unparseable
registry -> None, no crash), detector behavior against a synthetic
registry fixture (independent of the-custodian's live state, so stable
across canon changes) -- rogue ids flagged, all registered kinds incl.
grandfathered legacy patterns (AWQ-/DEC-/OH-/single-digit-task) pass,
template placeholders and .git/history dirs skipped, malformed yaml
doesn't crash the scan, dedup of repeated ids within a repo, no-op when
no registry is reachable.
Full consistency_check + consistency_sweep suite still green (128 tests,
no regressions from the C-31 addition).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Warn on YAML-block ids matching no kind in the canon work-record type
registry (~/the-custodian/canon/standards/work-record-types.yaml, override
via WORK_RECORD_REGISTRY). Detection only; registration of non-workplan
kinds is a later stage. Skips template placeholders and repos without the
registry available.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cards previously showed a hard 200-char snippet of description OR
rationale with no way to read the rest, and rationale was hidden
whenever a description existed. Long or dual-field cards now expand
in place (native <details>) to labeled full Description and Rationale
sections; short single-field cards render unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Gate cleared: 10 consecutive 8h zero-usage meter windows (07-10 14:00 → 07-13 22:00).
Removes create/list/update_workstream(_status) MCP tools, state://workstreams
resource, and the open_workstreams summary mirror. workstream_id field alias and
flows/workstream.yaml remain (still have live callers).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Documents the unmerged state-wp-0070-legacy-retirement branch (T03 full,
T04 low-risk half), the deferred field-alias + flows/workstream.yaml, and
the 7th-zero-window merge gate. Task statuses unchanged until merge.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Removes the redundant open_workstreams mirror field from StateSummary (schema,
router, MCP get_domain_summary reader, dashboard consumers + empty-state stub,
and tests). Consumers already preferred open_workplans, so this is the
low-risk half of T04.
Deferred (still have live callers — not yet retirement-ready):
- workstream_id query/body field alias on preferred routes — external
session-close curls/scripts fleet-wide still send it.
- flows/workstream.yaml — /flows/workstream/{id} routes are still served and
exercised by tests; retire only once no callers remain.
Staged on branch state-wp-0070-legacy-retirement — do not merge until the 7th
documented zero-usage window is captured.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Meter-gated removal (7 consecutive zero-usage windows reached). Deletes:
- MCP tools: create_workstream, list_workstreams, update_workstream,
update_workstream_status
- MCP resource: state://workstreams/{topic_slug}
- Dead helpers: _LEGACY_MCP_* maps, _legacy_mcp_deprecation,
_meter_legacy_mcp, _attach_legacy_deprecation, _update_workplan_legacy_impl
TOOLS.md keeps a retired→preferred migration map (per backlog). Removed the
now-dead STATEHUB_MCP_LEGACY_METER guard in conftest. Retargeted the
create_workplan error-skip test to the preferred tool; dropped alias-only tests.
Staged on branch state-wp-0070-legacy-retirement — do not merge until the 7th
documented zero-usage window is captured.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add ecosystem position to INTENT/SCOPE/README, publish hub-ecosystem-route-audit,
update workstream-coordinate capability relations, and record legacy-meter
weekly review evidence.
Alias tests monkeypatch _get/_post but _meter_legacy_mcp uses _client()
directly, so every pytest run recorded real usage and reset zero-window
retirement streaks. STATEHUB_MCP_LEGACY_METER=off skips metering; set in
tests/conftest.py. Verified meter counts flat across the alias suite.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>