I3281 — A workspace message is a typed provenance reference that validates in every checkout without the store
Add workspace:<workspace-id>/<conversation-id>#<message> to the shared Provenance reference grammar; validate it structurally against the tracked workspace declaration everywhere, accept a digits-only <message> as a positional reference flagged for pinning, and never consult .ai/local/ to decide validity.
BLOCKED wave 1 · p1 · implementation profile · parallel safe
Blocked. This issue cannot start until I3280 is done. The status is derived from that, not declared.
Objective
Add workspace:<workspace-id>/<conversation-id>#<message> to the shared Provenance reference grammar; validate it structurally against the tracked workspace declaration everywhere, accept a digits-only <message> as a positional reference flagged for pinning, and never consult .ai/local/ to decide validity.
Why
A reference that resolves only against checkout-local state fails in every other checkout: the 2026-10-18 adopter report (board p11, item 20) found committed candidates citing task:<id> from one checkout's ledger failing doctor 16 times elsewhere. The 2026-10-18 import's sources are positional (`conv#n`), so the grammar has to admit them while saying they are not yet pinned. Critique 2026-10-18: the import wrote prose references only, so validators reading structured fields would pass vacuously; the migration to typed positional entries belongs here because it needs only I3280 and I1301, not the vendor pipeline. The conversation component of the grammar waits on the owner's decision whether raw conversation ids may be public (finding conversation-ids-already-published); a refusal means an opaque alias resolved through the local store. The non-goal deferring a Claude Project contradicts owner source c239#9 and awaits the owner's confirmation. Proposed in ADR 0211 (A record promoted from a workspace cites the message it came from by a typed reference that validates in every checkout and resolves only where the store is held) (proposed; it carries no authority until the owner accepts it). Sources: chatgpt-majordomus:c267#2.
Current state
Neither provenance pattern (adr.v1, knowledge.v1) names a workspace message; the 2026-10-18 import wrote its sources only as prose chatgpt-majordomus:<conversation>#<n> in why, problem and record bodies.
Desired state
workspace: references validate (workspace declared, conversation id well-formed), a positional one warns 'not pinned', an undeclared workspace is refused.
Scope
- apps/majordomus-cli/src/plan.rs
- apps/majordomus-cli/src/capability/builtin/knowledge_base.rs
- .ai/repo/adrs/0211-a-record-promoted-from-a-workspace-cites-the-message-it-came-fro.md
- share/schemas/majordomus/adr/adr.v1.schema.json
- share/schemas/majordomus/knowledge/knowledge.v1.schema.json
- share/schemas/majordomus/intent/intent.v1.schema.json
- share/schemas/majordomus/milestone/milestone.v1.schema.json
- share/schemas/majordomus/issue/issue.v1.schema.json
- docs/KNOWLEDGE.md
- docs/PLANNING.md
- .ai/repo/skills/evolve/SKILL.md
Out of scope
- Reading the store (I3282)
Dependencies
- I3280READY An intent, a milestone and an issue carry provenance the way an ADR and a knowledge record do
- I1301DONE A workspace is a declared object of the layer; only its content is local
What waits on this
- I3173BLOCKED A synced workspace conversation proposes candidate records that cite their conversation and message, and nothing becomes canonical without an act
- I3273BLOCKED Each requirement of a campaign revision has a content-derived identity and is reconciled into the existing intents and issues
- I3282BLOCKED A workspace reference resolves to its message where the store holds it, and says 'not held here' where it does not
- I3284BLOCKED Every reference the 2026-10-18 import wrote is pinned to the upstream message it meant
- I3286BLOCKED A proposal from a workspace arrives as intent.propose carrying the workspace reference it came from
Acceptance criteria
- A clone with no .ai/local/ validates a record citing a declared workspace
- An undeclared workspace id is refused with the declarations that exist
- A digits-only message is reported as positional, not as an error
- The typed form is workspace:chatgpt-majordomus/<conversation>#<message> in provenance.derived_from; the prose form chatgpt-majordomus:<conversation>#<n> written by the 2026-10-18 import is recognised by a detector
- plan validate and knowledge check scan why, problem and record bodies for chatgpt-majordomus: and fail on any reference not also present as a typed provenance.derived_from entry of the same record
- Every prose workspace reference the 2026-10-18 import wrote is migrated into typed positional derived_from entries before the import commits
- A project rule under .ai/repo/rules/project and the promotion guidance in .ai/repo/skills state that a promoted record cites its workspace source as typed provenance, and the rule's proof is the detector's refusal
Validation
- majordomus plan validate
- bin/majordomus knowledge check
Evidence required
- case_a_workspace_reference_validates_without_the_store
Evidence
None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.
Timeline
- started
- —
- verified
- —
- completed
- —
Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.
Canonical record: .ai/repo/project/issues/I3281.yaml. Read it back with majordomus plan show I3281.