docs(skills): batch-lifecycle carries the closed-job write gate (cf. #439) - #450
Merged
Merged
Conversation
…439) The skill encoded the pre-#447 world: annotation writes gated on asset progress alone, with no job dimension. Left as it was, the next design session consulting it re-derives the hole that #439 closed. Decision 2 now states both dimensions and names OPEN_JOB_STATES as the one set the declaration (asset_actions) and the refusal (require_open_job) both read, so they cannot disagree; it also states why the batch gate never covered this — a job completing does not complete its batch. Decision 9 records the two rulings #447 shipped and a later reader would tidy away: frame-verb gating is job-level, and Finish job stays reachable on a settled last frame. Prose sweep for the same false sentence: docs/annotations.md, docs/jobs.md, docs/ui.md, docs/mcp.md, docs/mcp-walkthrough.md, mcp/_autostart.py, AnnotationPage.tsx and GalleryScreen.tsx all described one or two gates where there are now three. ui-capabilities gains the read-only transition, which is what a mid-session Finish now performs.
JArmandoAnaya
added a commit
that referenced
this pull request
Aug 10, 2026
…te (cf. #450) (#521) * docs(api): the annotations read is not gated on job or batch state The route description said reading is not gated on the batch being open. That is true but narrower than the rule the service enforces: neither job state nor batch state gates a read. The description is a published wire string, so openapi.json and the generated client are regenerated in the same change. * docs: the branch and merge affordances are settled, not deferred DESIGN.md's Provenance section recorded the version-control affordances as post-beta and pending a decision, and three passages promised they return with the model behind them. Neither half holds: the top-bar slots were removed on 2026-08-05, and the branch-and-merge model was settled on 2026-08-10 as superseded by the batch, review and release model the product already has.
JArmandoAnaya
added a commit
that referenced
this pull request
Aug 21, 2026
…te (cf. #450) (#521) * docs(api): the annotations read is not gated on job or batch state The route description said reading is not gated on the batch being open. That is true but narrower than the rule the service enforces: neither job state nor batch state gates a read. The description is a published wire string, so openapi.json and the generated client are regenerated in the same change. * docs: the branch and merge affordances are settled, not deferred DESIGN.md's Provenance section recorded the version-control affordances as post-beta and pending a decision, and three passages promised they return with the model behind them. Neither half holds: the top-bar slots were removed on 2026-08-05, and the branch-and-merge model was settled on 2026-08-10 as superseded by the batch, review and release model the product already has.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Governance only — no product code, no wire contract, no behaviour. #447 shipped the closed-job
write gate; the documents that a future session reasons from still described the world before it.
The skill (
.agents/skills/domain/batch-lifecycle/SKILL.md)OPEN_JOB_STATES = {pending, in_progress}joins the derived sets, andJOB_TRANSITIONSnowsays out loud that
completedhas no exit either.the job":
WRITABLE_PROGRESS→AssetNotWritable(409),OPEN_JOB_STATES→JobFinished(409
JOB_FINISHED), withJobService.markreading the same set. It namesOPEN_JOB_STATESas the single source that the declaration (
asset_actions, three dimensions, none optional)and the refusal (
JobService.require_open_job) both read, so the two cannot disagree — and itstates why the batch gate never covered this:
JobService.completedoes not complete thebatch, so a finished job ordinarily sits inside one that is still
in_annotation.frame-verb gating is job-level rather than frame-level (a
skippedframe is read-onlyper-frame and still needs its
Un-skip; the nav cluster is measured to one width — cf. Completed batch opens editable: edit functions remain active in the read-only workspace #423,Annotation top bar: consolidate image navigation into a centered cluster #416), and
completeis the job's declaration rather than the last frame's, soFinish jobstays reachable on a settled last frame.
The false-sentence sweep
Everything below claimed one or two lifecycle gates where there are now three. Each is prose;
none changes a rendered string or a wire field.
.agents/skills/frontend/ui-capabilities/SKILL.mdin_annotationbatch", and described the mode purely as an entry state — it is now also a transition a mid-sessionFinish jobperformsdocs/annotations.mdrequire_job,require_open_batch)"; and "The batch gate is the guard instead" underdeletehas noconfirm=docs/jobs.mdin_annotationbatch"; "annotate… isWRITABLE_PROGRESSand the batch gate together"docs/ui.mddocs/mcp.mdcompletedone is left alone" (it is now refused by the write's own gate); "writing is gated on the batch" in the #109 measurementdocs/mcp-walkthrough.mdsrc/visionset/mcp/_autostart.pyfrontend/ui-core/src/annotator/AnnotationPage.tsxreadOnlyderivation comment: "from both dimensions"frontend/ui-core/src/screens/GalleryScreen.tsxeditabledoor and the selection bar's) saying the kernel derives declarations "from both dimensions"The MCP test docstring that had written the hole down as a rule — "Writing here is legal — the
gate is the batch" — was already corrected in #447 and is quoted in the skill as the worked
example.
Found, not fixed
src/visionset/server/routes/annotations.py:60— "Reading is not gated on the batch being open:a label outlives the work that produced it." True and now incomplete: reads pass no job gate
either. It is a route description, so it is published verbatim into
openapi.jsonandfrontend/ui-core/src/generated/api.ts— a wire contract, not prose. Left alone deliberatelyrather than pulled into a docs PR; the sentence is not wrong, only narrower than the rule.
Test plan
Prose and comments only, so nothing new is asserted. The gate is the check.
bash scripts/check.shwas run in stages (the ~10-minute command ceiling), exit code per stage:The first pass of the frontend and browser stages failed for an environment reason and is
recorded rather than hidden: a fresh worktree has no
node_modules, sopnpm -r builddied onsh: 1: tsc: not foundand the three stages behind it never ran.pnpm install --frozen-lockfileand a re-run produced the codes above.
ruff check .also failed once, on an E501 this PRintroduced (
_autostart.py:9, 103 > 100); the docstring was rewrapped and re-run clean.Merged under the baseline-proof exception, step
python tests, cf. #444tests/kernelis red for two tests that have nothing to do with this diff.On this branch (
56da20f):On unmodified
mainat the merge-base856d2f8, clean tree, this machine, run by me now:Identical failure, identical assertion. The diff does not touch that surface: it changes
Markdown, two TSX comments and one Python module docstring — nothing in
kernel/adapters/ffmpeg_video_processor.py,kernel/services/ingest_service.py, their tests, orany ffmpeg invocation. What the failure exercises is video decoding of a deliberately corrupt
clip. The tracking issue is #444 (open); it is core-count dependent, not an ffmpeg-version
problem, and CI's
pythonjob installs the same package and passes.cf. #439, cf. #447, cf. #444 — no closing keyword anywhere in this PR, deliberately: it resolves
no issue.