Skip to content

deuriib/frame-ship

v0.17.1MIT

Frame-Ship methodology — from strategic intent to shipped release.

Changelog

All notable changes to this project will be documented in this file. Format based on Keep a Changelog.

[v0.17.1] — 2026-10-05

Changed

  • README badge now marks the repo public (was private).

[v0.17.0] — 2026-09-27

[v0.16.0] — 2026-09-26

Fixed. On opencode 1.18.x the twelve skills were never loaded, and installed agent files could never be updated. Both were silent: nothing errored, and the plugin reported success.

Why

  • The skills were copied into a folder nothing reads. The V1 lane wrote <config>/opencode/skill/<step>/SKILL.md — singular. opencode discovers skills from six roots and the singular directory is not one of them, so all twelve copies landed where no version of the tool looked. On the authoring machine: twelve directories and forty-six files on disk, and opencode debug skill listing none of them. INSTALL.md asserted the opposite ("V1 also accepts skills/"), which is where the belief came from.
  • Installed agent files froze at whatever version wrote them. Ownership was decided by comparing the recorded hash to the bytes on disk, so the only case that ever acted was the two already agreeing. A real content change from a new release could not overwrite the installed copy, and a hand edit was indistinguishable from it.

Changed

  • The V1 skills lane registers a path instead of copying files. It injects the plugin's own skills/ directory through the config hook (config.skills.paths), so opencode reads the repository files directly. One path, no copies, nothing to go stale, and a skill edit takes effect on the next session. The mechanism is not in opencode's published docs; it is verified on 1.18.32, where the session goes from 8 discoverable skills to 20 — all twelve loaded from the repo. The skills lane now writes no files on either generation.
  • Agent provisioning refreshes a stale copy and never a hand-edited one. A file we wrote whose bytes still match the manifest is rewritten on the next release; a file whose bytes differ was edited by a person, so it is left alone and named in the log as unmanaged.
  • The two opencode generations carry their own permission shape, and the code says so. V1's permission is a map keyed by bash and task; V2's permissions is an ordered list keyed by shell and subagent, which V2 obtained by renaming. Only the effects are shared. The V2 agent docs list the singular permission as a legacy field, so the two are never interchanged.
  • Dead helpers removed from shared.ts (listFiles, fileExists), which existed only for the copy-based skills lane.

Fixed

  • Prose-rewritten identifiers in documentation: subagent_depth for subagent_depth (a reader following that line would have configured nothing), no-subagents for no-subagents, and task → subagent in the V2 notes. A test now fails if any returns. The English phrase "subagent" remains correct in prose — docs/GLOSSARY.md requires both forms.
  • INSTALL.md no longer claims opencode reads a singular skill/ directory.

Upgrade note

If you are on opencode 1.18.x, delete <config>/opencode/skill/ if it exists. Everything in it was written by the removed copy-based lane and is inert. Nothing reads it, and the skills load from the repository either way. No config change is needed on any version.

[v0.15.0] — 2026-09-26

Breaking. Every skill, agent, file, and folder was renamed to ordinary words. Behaviour is unchanged: the same nine steps, the same order, the same four fields in the task note, the same seven hard rules. Only the names moved. Read MIGRATION.md before upgrading — there is a one-time cleanup, because the plugin writes skill and agent files into your opencode config folder and the v0.14 files are still sitting there under the old names.

Why

The v0.14 names were accurate for the people who wrote them and opaque to everyone else. quality-gate, PROPOSED_CHANGES.md, SPEC/HARD/GATE/DOMAINS and translate-to-spec all mean something simple. The first file any new contributor or agent read was AGENTS.md, and it was 100% jargon. A newcomer lost most of the framework before opening a single skill.

Changed

  • The twelve skills are now verbs. using-frame-ship → start-here, frame-intent → agree-the-goal, translate-to-spec → write-the-requirements, propose-changes → propose, review-security → check-security, review-architecture → check-design, execute-spec → build, quality-gate → review, verify-handoff → verify, ship-release → release, debugging → fix-a-bug, pull-request → open-a-pull-request. The frame-ship: prefix is unchanged.
  • The nine named people keep their names — barrera, vasquez, vera, santana, montero, subero, dauhajre, espinoza. Those are identity, not jargon, and renaming them would have been a rebrand dressed up as a simplification.
  • orchestrator is now montilla. This restores the original name rather than inventing one: agents/montilla.md is what the file was called before commit 7266339, and the pre-rename decision notes already list montilla (CEO) as a decider. The rename applies everywhere except inside skills/, where the old word is kept deliberately — the skills describe the method, and the method should not hardcode a persona.
  • The twenty-two other agents are named after what they do. review-refuter → skeptic, review-reliability → check-correctness, review-risk → check-what-could-break, review-resilience → check-failure-handling, review-readability → check-clarity, quality-assurance → run-the-tests, *-specialist → build-<domain>, and the seven domain reviewers → check-<domain>.
  • Files and folders. BRIEF-<slug>.md → GOAL-<slug>.md, OKR-<slug>.md → GOALS-<slug>.md, PROPOSED_CHANGES.md → PROPOSAL.md, GATE_REPORT.md → REVIEW.md, WAIVER.md → EXCEPTION.md, TEST_MATRIX.md → TESTS.md, IMPLEMENTATION_PLAN.md → PLAN.md, ARCHITECTURE.md → DESIGN.md, ADR-*.md → DECISION-*.md, dod-checklist.md → done-checklist.md. docs/briefs/ → docs/goals/, rules/subagents.md → rules/subagents.md. The numeric folder prefixes (10_design, 12_adr, 15_requirements, 20_backlog, 30_delivery, 40_workspace, 50_archive) were lexicographic ordering dressed up as a taxonomy and are gone.
  • HANDOFF.md and RELEASE_NOTES.md kept their names. They were already clear, and the plain-language versions (DONE.md, NOTES.md) were strictly worse. The rename rule was "clear names win", not "new names win".
  • Prose. ~10,700 lines of markdown rewritten across 139 files. The bulk was mechanical (the identifiers above); the rest was jargon that had no filename attached to it — packet → the 4-line note, dispatch → hand the work to, subagent → subagent, waiver → documented exception, domain owner → domain lead, blast radius → what else could break, HARD STOP → STOP. README.md, AGENTS.md, the four rules/ files and the eleven step skills were rewritten by hand.
  • The runtime card in plugins/opencode/skills.ts was rewritten to say the same thing twice: once in plain words, once as the exact tokens the rules are written in. It costs roughly 5–10% more prompt tokens. That is the accepted price — the card is the first thing the model reads and the first thing a person reads when inspecting the system prompt.

Added

  • docs/GLOSSARY.md — the style contract. Two columns: what we no longer say, what we say instead, plus the words that stay (the four task-note fields, the three verdict values) and the eight domains.
  • rules/writing.md — six writing rules, enforced by the test suite.
  • rules/guardrails.md grew a Commits section. The one-commit-per-work-unit rule existed only in skills/build/SKILL.md:38, which means it was invisible to every session that did not happen to be building. It is now in the file that is injected in full on every context, and it covers more than the build step did: one commit does one thing and the repo still works; a subject line needing an "and" is two commits; the body traces requirement → test → file; checks run before the commit, not after; no secrets; never amend or squash something already pushed; never rewrite history on a shared branch; and a work unit that has failed twice is escalated rather than committed a third time.
  • MIGRATION.md — the old→new table and the one-time config cleanup.
  • README.es.md — the Spanish entry point. The runtime stays English so it matches the tool and the model; a newcomer gets a plain-language door in their own language.
  • tests/smoke.test.mjs grew 16 → 18 tests, and gained two guards described below.

Fixed

  • rules/subagents.md and rules/subagents.md both existed. v0.15.0 wrote the replacement file but only text-replaced the references — the file move was never done, so the repo carried a stale half-converted original next to its replacement. The orphan is gone.

  • A prose sweep silently broke the agent runtime, twice. Rewriting subagent to subagent also rewrote the YAML key subagent: true and the tool names invoke_subagent / manage_subagents in all 31 agent files and agents.ts. That is not cosmetic: has("invoke_subagent") goes false, so toV1Permissions() emits task: deny and the coordinator quietly loses the ability to hand work to anyone. The same sweep renamed the local variable lockstepMatch in scripts/bump-version.mjs to version syncMatch, which was a syntax error — npm run version:check failed outright. Both are fixed, and both now have a test: one pins every identifier the runtime reads, the other scans all five plugin lanes for a prose-rewritten identifier.

  • open-a-pull-request was open-a-open-a-pull-request. The new name contains the old one, so the second pass re-applied the rule. The residue check now fails on any retired identifier anywhere in the active tree, which is what caught it.

  • bump-version.mjs was coupled to the word "lockstep". Its version anchor regex read Version lockstep:, so renaming the wording in AGENTS.md and rules/frame-ship.md would have silently stopped the version from ever syncing again. The anchor is now Version sync: in both the check and the transform.

Notes

  • Two machine words were left on purpose. HARD:subagents+… (a value in the task-note grammar) and subagent: true (a YAML key) are read by code, not by people. Changing them means changing every emitter, DESIGN.md and the parser in the same change. Both are documented as holdovers in docs/GLOSSARY.md.
  • "Test harness" was not banned. It is standard English. Only the "the tool the agent runs in" sense of harness is on the list, matched as phrases.
  • Frozen by design, and excluded from both rewrite passes: CHANGELOG.md, docs/specs/archive/, the 14 pre-rename ADR-*.md notes in docs/specs/decisions/, and the past review records in docs/specs/work/reviews/. They are records of what already happened, and rewriting them would be rewriting history. docs/goals/GOAL-subagents-naming.md and docs/goals/GOALS-subagents-naming.md are frozen too — they are the decision record for the word "subagent", so rewriting the term inside them made the record argue against itself.
  • Minor bump, not patch: every public identifier in the framework moved, and a plugin install that is not cleaned up keeps two sets of skills on disk.

[v0.14.0] — 2026-09-26

Fixed

  • The V1 harness lane never received references/, and could never be updated. plugins/opencode/skills.ts provisioned <xdg>/opencode/skill/<stage>/SKILL.md and nothing else, guarded by if (await fileExists(target)) continue;. Two defects compounded: a SKILL.md body cites references/<file>.md, and those files were never mirrored, so every reference was a dangling path on that lane; and never-overwrite froze the copy at whatever version first provisioned it, so it could not be updated either. Proven live before the fix — the V1 config dir on the authoring machine held exactly one file, SKILL.md, 62 lines, still reading tag after commit, while the repository was two releases ahead. v0.13.0 shipped a mandatory step that did not exist on that harness. Provisioning now mirrors references/** and refreshes copies it previously wrote, using a provenance marker (<!-- frame-ship-provisioned vX.Y.Z -->) to tell ours from a user's: a marked file with an older version is refreshed, an unmarked file is never touched. The log surfaces unmanaged stages so a frozen pre-marker install is visible instead of silent. plugins/opencode/shared.ts gains listFiles; withTimeout is now generic. tests/smoke.test.mjs asserts the mirror, the repo-source path, the marker and the guard's absence (12 → 13 tests).
  • CHANGELOG.md is now a --check target. The release tag's identity is tag name = package.json version = CHANGELOG.md header, and the third leg was asserted in prose only: a version with no ## [vX.Y.Z] section passed --check and CI, and a tag over it lied about the release. scripts/bump-version.mjs gains CHANGELOG.md as an assert-only 8th target — --changelog keeps the write because it stamps the date, --sync does not invent a header. 7 → 8 targets.
  • ship-release step 10's backfill commit was never pushed, so the ARCHIVE-RECORD.md on origin kept reading pending — the procedure guaranteed the invariant it forbade, deterministically. Step 10 now requires the backfill to be pushed.
  • Remote confirmation was a false negative waiting to happen. git ls-remote --tags origin vX.Y.Z was documented as printing two lines for an annotated tag; it prints one, because git filters the peeled ^{} line out for a bare pattern — reproduced against this repo's own v0.13.0. The one assertion that could distinguish an annotated tag from a lightweight one on the remote never ran. Now git ls-remote --tags origin refs/tags/vX.Y.Z "refs/tags/vX.Y.Z^{}", two lines required, with the reproduction in the text.
  • Two of the four tag verifications could not fail. git tag -l -n99 prints the commit message for an unannotated tag, so it never proved annotation; bare git describe --tags passes on a different tag and fails spuriously on a shallow clone. Replaced by git for-each-ref refs/tags/vX.Y.Z --format='%(contents:subject)' and git describe --tags --exact-match HEAD, each with the reason the old command was unsound.
  • The pre-check was blind to a remote-only tag and to a missing committer identity, so a partial prior run from another clone was invisible and git tag -a could hang on an interactive prompt. Now covers git ls-remote collision and git var GIT_COMMITTER_IDENT, and a re-run against a correct existing tag resumes at 8.3 instead of dead-ending into a destructive git tag -d.
  • ARCHIVE-RECORD.md mandated a field that did not exist. Step 10 backfilled **Tag object:** and searched for a pending in **Tag:**, which the template never had — an agent following it literally could conclude the backfill was already done and ship the exact pending violation the step exists to close. The template now declares **Tag object:** and **Backfilled by:**, and step 10 backfills only declared fields.
  • The terminal condition was assigned to two different steps by SKILL.md:51 and archive-record.md:50, so an agent could legitimately stop at step 9 and never backfill. Step 9 is now the single terminal condition; step 10 is the backfill.
  • The ship-release file count was wrong — skills/AGENTS.md said 8 (SKILL + 7 refs) when references/ holds 8 files, so the count written described the tree before tagging.md was added. Now 9 (SKILL + 8 refs).

Changed

  • ship-release steps 8-10 are now executable by the role that holds the stage. Per INV-009, orchestrator and every C-level owner are run_command-Prohibited, so a mandatory git step was a deadlock; the role binding also delegated mechanics to a devops agent that does not exist in the roster. §2b now names a run_command-capable agent (engineering-specialist / automation-specialist / quality-assurance) and the stage holder keeps the decisions. <branch> is no longer undefined — step 7 lands the release commit on main via the normal branch + review path, and publishing states its assumption before acting.
  • Every no-spec-lane path is an explicit N/A. Steps 2, 9 and 10 each state their N/A form, and the CHANGELOG.md identity leg documents its own exception. A step that cannot be executed is a deadlock, not a gate — and the no-spec-lane shape is 4 of the last 5 releases.
  • tagging.md §6 covers three rollback situations, not one. Un-pushed tag; pushed tag to withdraw (owner approval, then roll the version and changelog back); and tagged content that is wrong — revert forward as a new commit, bump, move the install pins, mark superseded, and leave the old tag forever. The prior text covered tag deletion only, which is never the answer to a bad release and destroys the release truth. A no-remote / no-push-access / offline release is now a documented dead end that records the blocker and keeps the correct local tag, instead of a reason to delete it.
  • Multi-spec releases and parallel lanes are covered. The annotation lists every included spec id (|-separated) and each spec's record carries the same tag; §7 states that tag refs are repository-global and extends the step-6.4 cross-lane guard to step 8.
  • One canonical procedure instead of four restatements. documentation-checklist.md now states the evidence required and explicitly forbids re-deriving the commands — the previous partial copy had already dropped 2 of 3 pre-checks and 2 of 4 verifications, so an agent working the checklist alone could ship a lightweight tag or a re-tag without tripping anything. tagging.md §8 prohibitions were deduplicated against the SKILL's "What I won't do".
  • INV-007 gained one explicit exemption. Step 10's backfill of the release commit sha, tag object sha and backfill actor into an ARCHIVE-RECORD.md written earlier in that same release is a same-release completion, not a retroactive alteration. Stated once in ARCHITECTURE.md:136 and mirrored into docs/AGENTS.md and docs/specs/AGENTS.md — previously the KB asserted both "never edit archive" and "you must edit archive" with no exemption.
  • 8 stale restatements of the release procedure corrected: README.md ×3 (stage table, artifact list, tree comment), rules/frame-ship.md:26, the plugins/opencode/skills.ts:82 prompt card, AGENTS.md ×2 (lockstep count 7 → 8), and the checklist's phantom "runtime line count" obligation — a transform that is a no-op in the current AGENTS.md, so the obligation had no target field.
  • references/readme-template.md no longer requires a releases/tag/vX.Y.Z link, a GitHub Release page that no shipped step creates while dead links are a gate violation. The badge now uses tree/vX.Y.Z, and the Release page is documented as optional with its gh release create invocation.

Added

  • docs/specs/12_adr/ADR-014-release-tag-mandatory-step.md — Status: accepted. The stage-contract change shipped in v0.13.0 violated rules/frame-ship.md hard rule 3 (ADR for contract changes); this records the decision, the three audit findings that forced each clause, and the rejected alternatives (--tag in bump-version.mjs, mandatory gh release create, signed tags).
  • docs/specs/15_requirements/REQ-ship-release-tagging.md — REQ-001..REQ-022 + REQ-NF-001..005, closing 6 blocking and 13 non-blocking audit findings.
  • docs/specs/50_archive/SPEC-ship-release-tagging/ — spec (AC-001..AC-025), GATE_REPORT.md, HANDOFF.md and ARCHIVE-RECORD.md, with the three Wave-A reviewer reports promoted in the gate report's directory history.

Notes

  • This release exists because v0.13.0 shipped unreviewed. Three independent reviewers audited that commit post-hoc and all three returned FAIL: the adversarial refuter (6 blocking), the readability reviewer (3) and the blast-radius reviewer (6). The orchestrator independently reproduced the five load-bearing claims before accepting them — and two were defects in the original implementation, not reviewer preferences: the git ls-remote two-line claim was factually false, and **Tag object:** was backfilled by a step whose template had no such field. The root cause per the risk reviewer: a chain-stage contract was changed and released without the gate the chain mandates, so the file count, the number of procedure sources and the executability of the new step were never checked by anyone but the author.
  • The v0.13.0 tag is untouched and this gate does not certify it. Its tag is valid and its tag identity holds, but the procedure it shipped was defective and is fixed only from here forward. Correcting forward is the ADR-014 §6 row-3 path: the old tag stays forever, and any correction ships as a new version with the old one marked superseded.
  • Minor bump, not patch: a plugin runtime path changed (V1 provisioning now writes files it previously left alone, and a new shared helper was added), the --check target set grew, and a stage contract gained a step. The V1 change is the reason this is not a patch — a user's V1 config dir now receives references/ and refreshed skill files.
  • Verified before release: mise run typecheck 0 errors, node --test 13/13, bump-version.mjs --check 8/8 at v0.14.0, the ls-remote and for-each-ref / describe --exact-match commands reproduced against v0.13.0, and the --check false-green reproduced by stripping the changelog header.
  • Open conditions, owned with expiry: COND-001 no CI job asserts a release was tagged (automation owner, next minor); COND-002 a pre-marker V1 install is reported unmanaged and never auto-refreshed — the operator deletes the stage dir once, and the authoring machine's copy was exactly this case (automation owner, next minor); COND-003 the step 8-10 run_command dispatch is written, not machine-checked (engineering owner, next minor); COND-004 Wave B remediation was verified by the orchestrator against artifacts rather than by an independent reviewer wave (engineering owner, next release with a code change).
  • Deviations recorded, not hidden. The spec was authored after its work completed, so the 20_backlog/ round-trip is unverifiable in git history and the archive move is A rather than R — no prior blob existed to rename from. There is no PROPOSED_CHANGES.md for this release; the work was done under a direct owner instruction. Both are in the ARCHIVE-RECORD.md §Notes.
  • docs/specs/50_archive/SPEC-repo-hygiene/HANDOFF.md:73 records the weaker git tag v0.12.0 form and is not edited — it is a historical execution record, and the practice it documents is precisely what tagging.md §8 now forbids. The retroactive v0.12.1 tag (08fa07c) does not satisfy tagging.md §1; no grandfathering clause exists, by design.
  • --tag automation inside bump-version.mjs remains deliberately rejected: the script has zero git invocations by design, and tagging is a stage decision. CI release-tag assertion is the natural follow-up (COND-001).

[v0.13.0] — 2026-09-26

Added

  • skills/ship-release/references/tagging.md — canonical release-tag mechanics: tag identity as a three-way check (tag name = package.json version = CHANGELOG.md release header), the annotated-tag rationale, the annotation-message shape (version — ship-type — spec-id — gate <verdict> + highlights + Refs: <REQ-IDs>), a 4-substep procedure (pre-check → create → verify → publish), the verification command table, the backfill field map, the retract/rollback recipe, and 7 prohibitions.
  • skills/ship-release/SKILL.md — tagging promoted from a parenthetical ("tag after commit") in step 7 to a first-class step: step 8 tags (4 ordered substeps), step 9 closes the release only once git ls-remote --tags origin vX.Y.Z prints the tag object sha, step 10 backfills the archive record. The tag is now an OUT artifact, and an untagged or unpushed release is a STOP condition.
  • skills/ship-release/references/documentation-checklist.md — §2 gains step 5 Tag & Publish the Release; §3 gains the prohibition on shipping without a matching annotated tag on the release commit, published to origin.

Changed

  • skills/ship-release/references/archive-record.md — **Commit(s):** and **Tag:** are now declared forward references at write time (6.3 precedes the release commit at 7 and the tag at 8): the template records the planned tag name and pending for the sha, and a new rule requires the step-10 backfill. A literal pending in a shipped record is a gate violation. This closes a latent contradiction where the record mandated values that did not yet exist.
  • README.md Contributing #6 now specifies an annotated git tag -a vX.Y.Z on the release commit, published to origin — matching what all 6 existing tags already are.
  • skills/AGENTS.md — ship-release file count 7 → 8 (SKILL + 7 refs), WHERE TO LOOK Out column gains the tag, and a new convention states the step 8/9/10 tag lifecycle.
  • AGENTS.md — WHERE TO LOOK release row gains the annotated tag; the CODE MAP entry for scripts/bump-version.mjs now states that the script is file-only, runs no git commands and does not tag.

Fixed

  • The release tag was never a step, so nothing enforced it. README.md declared "the tag is the release truth" while v0.12.1 shipped with a changelog entry and no tag (self-documented at CHANGELOG.md:41). Tagging is now gated on the same terms as changelog, lockstep, and rollback.

Notes

  • Tag type is annotated, unsigned: annotated so the tag carries a tagger identity and message and resolves under git describe; unsigned so the step cannot fail on a missing GPG/SSH key. Provenance rests on the release commit sha recorded in ARCHIVE-RECORD.md, not a signature.
  • Minor bump, not patch: a chain stage gained three ordered process steps and a new contract artifact (the tag), and the archive-record forward-reference contract changed. Existing releases are unaffected — the change is additive.
  • This release dogfoods the new step: v0.13.0 is tagged by step 8, verified by git ls-remote, and published, rather than tagged ad hoc.
  • No spec lane: this was a direct owner instruction to close a release-mechanics gap, executed outside the chain, so ship-release step 6 archiving and step 10 record backfill are N/A — there is no 50_archive/<spec-id>/ to promote or backfill. Precedent: v0.12.1–v0.12.3 also shipped with no spec lane. Consequence: the REQ-ID → test → artifact → gate verdict trace has no REQ-ID for this release and this changelog entry is the only evidence.
  • --tag automation inside scripts/bump-version.mjs deliberately deferred: the script has zero git invocations by design and a --tag flag would change that contract. gh release create publishing is also out of scope.
  • Verified before release: mise run typecheck 0 errors, node --test 12/12, bump-version.mjs --check 7/7 at v0.13.0, all tagging.md citations resolve.

[v0.12.3] — 2026-09-26

Changed

  • Test strategy ownership moved to propose-changes: skills/execute-spec/references/testing-template.md → skills/propose-changes/references/test-strategy.md. The template was a passive reference in the only stage where it could no longer change the design, and nothing forced it to be read — its own stage table already claimed propose-changes authors the test plan, so the file contradicted the chain.
  • PROPOSED_CHANGES.md gains a required §Test Plan (REQ-ID → Test/Evidence ID mapping, declared coverage floors, environment/cleanup), matching the shape in references/proposal-template.md; references/test-strategy.md owns the standard (canonical paths, floors, 13-type catalog). Every REQ-ID owes ≥1 Test ID (code) or ≥1 Evidence ID (non-code), so the obligation binds all 8 domains, not engineering alone.
  • skills/propose-changes/SKILL.md: Contract STOP rejects a plan-less proposal ("not approvable"), process step 4 authors the plan and freezes it at approval, "What I won't do" forbids approving a proposal with uncovered REQ-IDs, and the approver checklist carries a Test Plan item.
  • skills/execute-spec/SKILL.md: step 6 executes the frozen plan and records results in TEST_MATRIX.md; a missing test type or a lowered floor routes back to propose-changes as a plan amendment instead of being decided at the implementation stage.
  • skills/quality-gate/references/engineering/quality-assurance-review.md and skills/verify-handoff/references/dod-checklist.md now verify the plan against the matrix and measure coverage against the declared floors — a skipped plan fails the gate instead of passing silently.
  • Trimmed the moved file: the chain ascii + 9-row stage-lifecycle table (already owned by skills/AGENTS.md, going stale) and the standalone plan template (folded into proposal-template.md). skills/AGENTS.md, rules/frame-ship.md and README.md updated (ownership line, file counts execute-spec 4 / propose-changes 4, two new anti-patterns, hard-rule 5 gains the no-plan/no-approval clause).

Notes

  • No new artifact or singleton: the plan lives inside PROPOSED_CHANGES.md, so the ARCHITECTURE.md:150 traceability chain and the ship-release purge allowlist are unchanged. RELEASE_NOTES.md untouched per patch-release cadence (v0.12.1, v0.12.2); no spec lane to archive.
  • Patch bump (not minor) per repository cadence: no runtime code changed. The chain contract change is additive and non-breaking — existing proposals gain one required section, and no plugin, agent or hook file was modified.
  • Verified before release: mise run typecheck 0 errors, node --test 12/12, bump-version.mjs --check 7/7 at v0.12.3, all relative reference paths resolve.

[v0.12.2] — 2026-09-26

Changed

  • Brief/OKR citation contract normalized to the paired form. Five briefs (remove-tool-mapping, residual-cleanup, single-demo-docs-fix, skill-naming, skill-refs-normalization) had their OKR set appended as an H1 # OKRs: <slug> block instead of shipping the paired OKR-<slug>.md file; each block was extracted byte-identical and replaced by the **OKRs:** docs/briefs/OKR-<slug>.md header pointer. The 11 briefs that already shipped paired files now declare the same pointer (coverage 17/17), making the pairing auditable with one grep. OKR-agent-templates.md backfilled to close the only orphan pair, marked unverified because the brief's 68 global agents baseline is not reproducible.
  • skills/frame-intent/SKILL.md + skills/translate-to-spec/SKILL.md: the frame-intent handoff packet is now anchorless. The hardcoded SPEC:<brief-path>#OKRs anchor (4 sites) never resolved - no paired brief has an OKRs heading, and the 5 inlined ones used a slug-suffixed H1 anchor - and it violated ARCHITECTURE.md#packet-grammar, where anchors = req-id *( "," req-id ) and no REQ-ID exists before translate-to-spec mints one. The paired OKR travels as a named path, never as a fifth packet field.
  • skills/translate-to-spec/SKILL.md reads the paired OKR file and escalates an orphan brief back to frame-intent instead of authoring OKRs at a stage that does not own intent.
  • docs/AGENTS.md, skills/AGENTS.md, README.md: state the paired OKR-<slug>.md filename and the 1:1 pairing rule where they previously said only "OKRs".

Fixed

  • Prohibition text in docs/AGENTS.md and skills/frame-intent/SKILL.md is worded without the literal anchor token, so rg '#OKRs' skills/ remains a clean automated gate instead of matching its own rule.

Notes

  • Historical citations of the form BRIEF-<slug>.md#OKRs + OKR-<slug>.md are retained in docs/specs/50_archive/, 15_requirements/, 20_backlog/SPEC-multi-default-people.md and 40_workspace/quality-gate/grilling-integration/GATE_REPORT.md, per INV-007 (Historical Immutability). 15_requirements/REQ-skill-naming-engineering.md now points at a permanently absent anchor, as it did before this change (the heading it referenced was a slug-suffixed H1).
  • v0.12.1 had a changelog entry but no tag; the tag is added retroactively on 08fa07c with this release.
  • Patch bump (not minor) per repository cadence: 0.12.0 to 0.12.1 shipped the V1/V2 dual-harness plugin and the packet-grammar contract change 5c5bfd3 as a patch. No runtime code changed in this release.

[v0.12.1] — 2026-09-26

Added

  • V1 lane: experimental.session.compacting hooks in skills.ts + guardrails.ts (reminder / full guardrails into output.context) — parity with the V2 ctx.session.hook("compaction") pair; the previous "V1 has no compaction hook" comments were false (hook exists since V1 1.18.29).
  • plugins/opencode/agents.ts: toV1Permissions() — least-privilege V1 permission map (read|list|glob|grep|edit|bash|task|webfetch|question|skill, allow/deny, mirroring the V2 effects) + hidden emitted through the config hook; the boolean tools map is kept only as a legacy hint.
  • tests/smoke.test.mjs: V1-contract tests (d) — type-only @opencode/plugin import, hybrid {id, setup, server} export shape, logger/compaction/permission-map presence (suite now 12 tests).

Changed

  • Hybrid export shape across all four plugin files: { ...definePlugin({ id, setup }), async server(ctx) } — the official dual-version pattern (V2 reads id/setup and ignores server; V1 ≥ 1.18.29 calls server()), replacing Plugin.define(...) + (plugin as any).server = mutation.
  • V1 skill provisioning now writes plain <stage>/SKILL.md dirs with the unchanged frontmatter name: <stage> (V1 resolves skills by name and documents lowercase-hyphen names with dir == name), and the V1 card/pointers/bootstrap render with an empty skill prefix (skill(using-frame-ship), →frame-intent(...)); the V2 lane keeps frame-ship:<stage> ids byte-identically.
  • V1 agent config hook merges field-wise into any pre-existing config.agent[id] entry (user model/temperature/options survive) instead of wholesale replacement.
  • Docs: plugins/opencode/INSTALL.md rewritten as dual V1+V2 install (plugin vs plugins keys, per-harness verify sections, V1 lane notes); README.md + AGENTS.md + plugins/AGENTS.md corrected (V1+V2 runtime, plugin id frame-ship-agents, no default agent set).

Removed

  • plugins/opencode/agents.ts: removed builtin plan/build lane enrichment — deleted PLAN_TAG/BUILD_TAG, PLAN_DESCRIPTION/BUILD_DESCRIPTION, PLAN_SUFFIX/BUILD_SUFFIX, planPermissions() and the plan/build ctx.agent.transform block; builtins now ship untouched (was REQ-007 sponsor fold-in).

Fixed

  • Plugin load failure on both harness generations: value import { Plugin } from "@opencode/plugin" made the entry fail (Cannot find package ... node_modules/@opencode/plugin/index.js) whenever node_modules was missing or broken (as in this workspace). @opencode/plugin is now import type only and definePlugin (identity, matching upstream) lives in shared.ts — true zero runtime dependency; verified by loading the composed entry from a directory with no node_modules.
  • V1 logging was a silent no-op (ctx?.app?.log?. does not exist on V1) → now ctx.client.app.log({ body: { service, level, message, extra } }) in all three lanes.
  • V1 skills never provisioned on Windows (target dir skill/frame-ship:<stage> contains :, invalid on NTFS — ensureDir failed and was swallowed) and the card called skill(frame-ship:<stage>) while frontmatter carried unprefixed <stage> (NotFoundError even on POSIX).
  • V1 agents were unenforced: V1 ≥ 1.18.32 never reads value.tools from config agent entries, so frame tool restrictions never applied (default allow-all). The permission map is merged last and V1 evaluates with findLast, making it authoritative.
  • Stale support claims: plugins/opencode/INSTALL.md "V1 not supported" (see v0.7.0), README.md/AGENTS.md "sets the orchestrator default" (no default is set).

[v0.12.0] — 2026-09-23

Added

  • .github/workflows/ci.yml: first CI pipeline — 2 jobs (typecheck + tests + version lockstep) on push:main + pull_request, permissions: contents: read, action refs API-verified, no secrets (SPEC-repo-hygiene).
  • tests/smoke.test.mjs: zero-dep node:test suite (9 tests): registry sync (12 entries + bidirectional negative), hook marker guards, 5 Antigravity fixture replays; wired as npm test glob form.
  • package-lock.json: committed lockfile for npm ci reproducibility — registry-default (npm 10 + 11 both dry-run clean, platform optionals present, no explicit mirror URLs).

Changed

  • Doc-truth sweep across README.md, AGENTS.md, plugins/AGENTS.md, hook headers: three-plugin split-lane reality (guardrails lane + composed entry frame-ship.ts), Registers 12 skills, bun-runtime claims removed, withTimeout claim scoped to shared.ts setup helpers (SPEC-repo-hygiene).
  • plugins/opencode/agents.ts: plan/build enrichment comment reconciled with REQ-007 design (description overrides intentionally commented; permission persistence host-reconciled) — comment-only, zero logic (SPEC-repo-hygiene).

Fixed

  • CI action pin jdx/action-mise@v3 (API 404) → jdx/mise-action@v3 (verified + v3 ref exists).
  • CHANGELOG repairs: restored v0.6.1, v0.7.0 sections; v0.3.0 heading order normalized.
  • False attestations corrected: CI rollback path now the verified two-SHA revert (a83347b + feb9014); lockfile mirror provenance corrected.

[v0.11.0] — 2026-09-23

Added

  • rules/skills.md: skill-loading policy — chain skills first (using-frame-ship pre-loaded, stage skill ONCE, no skill = STOP), then at most 1-2 external skills on trigger match; chain wins on conflict; external skills never waive hard rules, gates, or load order; cite by path + anchor (reference-only). Loaded natively from rules/ on agy; distilled into POINTERS on OpenCode.
  • rules/frame-ship.md: ## External skills (complement the chain) section mirroring the policy above.

Changed

  • skills/using-frame-ship MANDATORY LOAD ORDER step 2 now states the external-skills complement (after stage skill, budget of 1-2, precedence, reference-only).
  • POINTERS skills line replaces the vague "always load skills proactively" wording with the chain-first + external budget rule; COMPACTION_REMINDER typo (metions) fixed.
  • AGENTS.md + skills/AGENTS.md document the internal-vs-external loading convention and list all four rules/ files.
  • rules/subagents.md wording simplified (dropped retired multi-subagents mode mention).

[v0.10.0] — 2026-09-22

Removed

  • Standalone skills/git-worktree/ skill (SKILL + 4 refs): merged into skills/execute-spec/references/worktree-annex.md as a supporting annex. Plugin now registers 12 frame-ship:<stage> skills (was 13); frame-ship:git-worktree trigger retired — parallel lanes are invoked via execute-spec + the annex. Security guards, pwsh flow, and people announce wording preserved by reference inside the annex.

Added

  • skills/ship-release/references/archive-record.md: 50_archive/<spec-id>/ARCHIVE-RECORD.md template (spec, gate verdict, commits, tag, promoted/purged lists, ADR link, rollback plan).
  • skills/using-frame-ship/references/challenge-round.md: single source for shared C1–C4 opt-in challenge mechanics (glossary, opener/exit, one-at-a-time, warmth, masking Ley 172-13, N+1, stall breaker).

Changed

  • ship-release archive is now promote-then-purge in 5 ordered substeps: git mv to 50_archive/<spec-id>/, promote GATE_REPORT.md + HANDOFF.md BEFORE purging, write ARCHIVE-RECORD.md, purge allowlist only (PROPOSED_CHANGES/IMPLEMENTATION_PLAN/TEST_MATRIX/HANDOFF of that spec + quality-gate/<spec-id>/), verify other lanes untouched. Purging evidence without promoting it is now an explicit violation.
  • ship-release refs 6 → 3 core (release-notes, changelog, documentation-checklist + archive-record); readme/install/migration-guide templates conditional on ship-type=deploy with breaking changes.
  • Singleton-per-lane naming fixed as the single convention: scope comes from the directory (<domain>/, quality-gate/<spec-id>/), never from -* filename suffixes; kebab-case only for per-reviewer gate verdicts. docs/AGENTS.md + docs/specs/AGENTS.md corrected (they previously mandated <spec-id> suffixes).
  • ADRs are now conditional: only when a change breaks/creates an invariant, adds a component, or changes a cross-domain contract — within-contract changes get an architecture review only, no ADR. Status: proposed with code already merged = gate FAIL.
  • Duplicate ADR-002 renumbered to ADR-012-agents-to-root.md (one number = one file, numbers never reused); ADR-007-grilling-integration proposed → accepted.
  • Ghost API_CONTRACTS.md reference removed from translate-to-spec + review-architecture (file never existed; interfaces live in ARCHITECTURE.md Components table); architecture-template.md moved to review-architecture/ as template owner.
  • C1 (frame-intent), C2 (propose-changes), C3 (quality-gate), C4 (verify-handoff) reduced to trigger + budget lines citing the shared challenge-round.md.

[v0.9.0] — 2026-09-22

Changed

  • Split the single-file OpenCode plugin into two independent plugins plus a shared module:
    • plugins/opencode/skills.ts (id frame-ship): skills lane, system injection (workflow card + pointers + bootstrap), compaction reminder.
    • plugins/opencode/agents.ts (id frame-ship-agents): agents lane (parse, provision, transform, orchestrator default).
    • plugins/opencode/guardrails.ts (id frame-ship-guardrails): guardrails lane — full rules/guardrails.md injected on session context, minimal one-line-per-domain set injected on compaction so the guardrails survive context compression behind the [frame-ship-guardrails v…] marker; falls back to the minimal set when the rules file is unreadable.
    • plugins/opencode/shared.ts: version lockstep target (header + const VERSION) + bounded filesystem helpers; no default export, never listed as a plugin entry.
    • plugins/opencode/frame-ship.ts becomes the composed entry point (still package.json main) that runs all three lanes under the original id — package installs and existing plugins: ["./plugins/opencode/frame-ship.ts"] entries keep full behavior with zero changes. Never list it together with skills.ts.
  • Version lockstep bump target moved from plugins/opencode/frame-ship.ts to plugins/opencode/shared.ts (7-file lockstep count unchanged).
  • mise run typecheck now checks all five plugin sources with --moduleResolution bundler, mirroring how the loader resolves the extensionless relative imports between the split files.

[v0.8.0] — 2026-09-21

Added

  • Canonical repository-local agent subsystem in /agents containing 31 structured agent definitions across 4 architectural tiers:
    • Tier 1: 1 Orchestrator (orchestrator.md / montilla) as primary chain entry (mainAgent: true) and sole dispatcher.
    • Tier 2: 8 Domain Owners (vasquez.md, barrera.md, dauhajre.md, subero.md, vera.md, santana.md, montero.md, espinoza.md) governing domain chain execution and gates (mainAgent: true, subagent: true).
    • Tier 3: 8 Fused Domain Specialists (engineering-specialist.md, security-specialist.md, finance-specialist.md, legal-specialist.md, marketing-specialist.md, people-specialist.md, revenue-specialist.md, automation-specialist.md) consolidating previous 70+ fragmented micro-roles into 1 authoritative craftsman per domain (subagent: true).
    • Tier 4: 14 Methodological Quality Gate Reviewers (7 engineering wave + 7 domain gate auditors) with independent verification roles (subagent: true).
  • Universal File Authoring: Enabled write_to_file and replace_file_content across all 31 agents in agents/ ensuring all roles can author artifacts, specifications, audit findings, and reports, while command execution (run_command) remains strictly restricted to authorized execution specialists (engineering-specialist, automation-specialist, quality-assurance).
  • Comprehensive rename of QA to quality-assurance: Renamed agents/qa.md to agents/quality-assurance.md, renamed skills/quality-gate/references/engineering/qa-review.md to quality-assurance-review.md, and updated all routing tables, checklists, and gate report templates across skills/ and agents/.
  • Formally recorded architectural decision ADR-010-canonical-agents-roster.md in docs/specs/12_adr/ and updated docs/specs/10_design/ARCHITECTURE.md to v1.1 formalizing invariants INV-009 through INV-012.

Changed

  • Standardized operational execution nomenclature from multi-subagents to subagents across all active stage skills, reference templates, catalogs (AGENTS.md), and packet envelopes (HARD:subagents+<constraints>).
  • Formalized canonical contract string W-SUBAGENTS and indexed ADR-009-subagents-naming.md in docs/specs/12_adr/.
  • Preserved historical immutability under Option A (past releases, closed gate reports in 40_workspace/, and completed briefs remain untouched).
  • Standardized execution mode to multi-subagents across the Frame→Ship chain (skills/translate-to-spec/, skills/execute-spec/, skills/quality-gate/, skills/git-worktree/, and canonical templates). Removed the dual-track single methodological mode everywhere in-chain.
  • Defined deterministic sequential degradation contract (W-SEQ) for single-thread or non-task harnesses, maintaining full-wave gate and review rigor without silent downgrade.
  • Unified quality gates to full-wave only with adversarial review-refuter prior to qa (min-gate removed).
  • Recorded architectural decision ADR-008-multi-default.md in docs/specs/10_design/.

[v0.7.0] — 2026-09-19

Added

  • V2-only port (plugins/opencode/frame-ship.ts, Plugin.define({ id: "frame-ship" }), @opencode/plugin@2.0.9): skills lane via ctx.skill.transform (13 frame-ship:<stage> skills, never overwriting user skills), system injection via ctx.session.hook("context") as {type:"text", text} parts (workflow card + guardrails + pointers + live using-frame-ship bootstrap, idempotent), compaction reminder via ctx.session.hook("compaction").
  • plugins/opencode/package.json directory manifest (main: ./frame-ship.ts) marking the explicit plugin root; .ts path unchanged.
  • plugins/opencode/INSTALL.md rewritten for V2 (package install via opencode plugin add, local file via .opencode/plugins/, V2 behavior deltas).

Changed

  • Path resolvers now match the kept layout (<root>/plugins/opencode/frame-ship.ts → <root>/skills|agents); mise run typecheck runs from repo root against the real path.
  • hasMarker() accepts V2 {type:"text", text} system parts (string parts still accepted).

Removed

  • V1 implementation: @opencode-ai/plugin dep, config hook, experimental.chat.system.transform / experimental.session.compacting hooks, config.agents/config.agent mirror writes, default_agent/subagent_depth writes (V2 has no subagent_depth equivalent).

Known issues

  • Agent roster degrades gracefully: V2 AgentEditor has no add, so the 74-key manifest updates existing agents in place only (verified: general/explore pick up roster body + mode) and skips missing keys; montilla default applies only when present. File-based .opencode/agents/ discovery is the V2-native path for new agents (follow-up, needs layout change).
  • Live model-request hook firing not exercised against a model (insufficient account funds at verify time); hook logic + idempotency proven via mock harness (4 context parts + marker, 1 compaction part, rerun adds 0) and 13/13 skills + active status via server API.

[v0.6.1] — 2026-09-17

Added

  • C-level chat roster declutter: optional hidden in AGENTS_MANIFEST + config.agents/config.agent mirror; 8 C-level mode:all hidden:true (barrera, dauhajre, espinoza, montero, santana, subero, vasquez, vera), montilla visible, 0 subagent flags; backward-compatible exact shape hidden:true ([engineering], SPEC-hidden-flag-engineering; gate OPEN 4/4, DoD PASS; restart opencode to take effect).
  • Agent roster in the single-file plugin: static 74-key AGENTS_MANIFEST (montilla primary + 8 C-levels + 65 specialists, espinoza-specialist alias) + loader (resolveAgentsDir, readTextFile, parseAgentFile) + config.agents/config.agent mirror with default_agent="montilla" + subagent_depth=2, never clobbering user overrides ([engineering], SPEC-agents-into-plugin-engineering; gate OPEN 6/6, DoD PASS; .opencode/plugins/frame-ship.ts v0.6.1, 403 lines, zero deps, restart opencode to take effect).
  • Loader hardening: BOM/whitespace strip + unclosed-fence fallback, guarded defaults on miss lanes, READ_TIMEOUT_MS=2000 race-as-miss, independent mirror records ([engineering], same spec; remediation 253c94e, 92a4941, ab64ca1, 14eaa4e, evidence matrix C-001..C-005).

Known issues

  • Plugin-only ship per CEO ruling: agents/ stays untracked — fresh-clone installs run degraded via graceful miss lanes until roster packaging is resolved (track after secret/PII scan, or external roster source). No breaking changes; rollback = single-file git revert, ETA < 15 min.

[v0.5.0] — 2026-09-17

Added

  • Antigravity CLI (agy) plugin at repo root: plugin.json + hooks.json + hooks/*.ts via bun (context-inject PreInvocation, safety-gate PreToolUse, format-note PostToolUse) + rules/frame-ship.md verbatim cards, 1:1 context parity with the opencode plugin, skills/ reused verbatim ([engineering, security, automation/ops], SPEC-agy-plugin-engineering; gate OPEN 5/5 + waiver, DoD PASS).
  • git-worktree supporting skill: isolated parallel SPEC lanes (max-2, repo-local worktrees) with fail-closed hygiene + consent/announce flow ([engineering, automation, security, people], SPEC-git-worktree-engineering, SPEC-git-worktree-automation, SPEC-git-worktree-security, SPEC-git-worktree-people; gate OPEN 9/9, DoD 47/47).
  • Supporting skills integration: git-worktree, debugging, pull-request formally catalogued in skills/AGENTS.md (13 dirs) + opt-in triggers in using-frame-ship + conditional Previous/Supporting/Next in Chain Contracts of propose-changes, execute-spec, quality-gate ([engineering], SPEC-supporting-skills-integration; gate OPEN 4/4, DoD PASS).
  • debugging supporting skill: Iron Law + 4-phase root-cause before fixes with 3-failure rule (stop after 3 failed fixes, question architecture, escalate — never silent Fix #4); skills/debugging/SKILL.md + 3 refs (root-cause-tracing, defense-in-depth, condition-based-waiting) ([engineering, automation/ops], SPEC-debugging-engineering; gate OPEN 6/6 incl. security + automation, DoD 6/6 TEST_MATRIX-debugging).
  • pull-request supporting skill: frame-ship port of Gentle AI branch-pr v2.0 — branch naming + PR body template + 400-line review budget + Conventional Commits, local checks mapped to mise run typecheck ([engineering, automation/ops], SPEC-pull-request; min gate OPEN 4/4, DoD PASS, review-security/architecture waived with rationale).

Changed

  • frame-intent classify-first elicitation: spike/bounded/architectural classification + HARD-GATE + one-at-a-time questions + 2–3 framings/YAGNI + decompose rule + sectioned approval + self-review + Red Flags ([engineering, people], SPEC-brainstorm-frame-intent-engineering; ADR-006; gate OPEN 5/5, DoD PASS). Brief template gains Classification/Framings-considered/Approval fields; outputs stay BRIEF + OKRs.

Removed

  • skills/using-frame-ship/references/tool-mapping.md (engineering, SPEC-remove-tool-mapping-engineering): CEO-only dispatch contract now single-sourced in using-frame-ship/SKILL.md + checklist + AGENTS.md + plugin; SKILL §3/§5 reworded, zero live pointers (gate OPEN, DoD PASS).
  • README.md stale tool-mapping prose (engineering, SPEC-residual-cleanup-engineering): L97 descriptor + L236 roadmap clause reworded; front-door exact, roadmap honestly still pending (gate OPEN, DoD PASS).

[v0.4.0] — 2026-09-16

Added

  • Per-stage commit closings (guidance only): every stage SKILL.md ends with a work-unit commit step + copy-paste example; shared format lives in skills/using-frame-ship/references/commit-convention.md.
  • execute-spec per-task rule: one commit per approved task/REQ-ID with REQ-ID → test → artifact in body; implementation-plan.md steps map 1:1 to commits; test-matrix.md gains Commit column.

Changed

  • Removed vendored agent templates (agents/ — 69 files, 9 subdirs): skills now reference domain roles directly without requiring template reads; simplifies dispatch model across all 9 stages.
  • Simplified dispatching: removed task(subagent_type="general") max 2 parallel with template-read orders; replaced with domain role understanding (skills/execute-spec, skills/quality-gate, skills/frame-intent).
  • Fixed workspace path convention: <agent> → <domain> in docs/specs/40_workspace/<domain>/ paths (skills/propose-changes, skills/review-architecture, skills/review-security).
  • Updated skills/AGENTS.md: removed vendored craft references, simplified role owner descriptions, removed execution mode template references.
  • Updated skills/quality-gate/references/gate-report.md: Load Evidence checklist now checks domain role understanding instead of template reads.

Removed

  • agents/ directory (69 files, 9 subdirs): vendored agent templates removed from repo root; skills reference domain roles directly.

[v0.3.3] — 2026-09-16

Changed

  • Commit convention rewritten with work-unit scope syntax type(<stage>/<work-unit>): subject for all 9 stages; splitting rules mandate separate commits per distinct work unit (REQ-ID, brief, spec, proposal, ADR, review, gate, handoff, release); batching rules allow grouping only when plan explicitly groups or changes are tightly coupled (SPEC-commit-convention-v2; gate OPEN, DoD PASS).

[v0.3.2] — 2026-09-16

Changed

  • Concise plugin prompt injections: .opencode/plugins/frame-ship.ts 223→156 lines (−31.3%, 11,098→7,620 chars), string literals + header only, zero behavior change (INTENT-2026-09-16-concise-plugin-prompts, REQ-001..REQ-006; gate OPEN, DoD PASS; restart required).
  • Single CHAIN const replaces 4x chain-order literals; guardrails as greppable 1:1 numbered checklist (14/14).

[v0.3.1] — 2026-09-16

Changed

  • Vendored agent craft moved skills/templates/agents/ → repo-root agents/ (69 files, 9 subdirs, bytes-exact); live pointers rewritten in 7 files; skills/templates/ removed (SPEC-003-agents-to-root; refs: docs/specs/10_design/ADR-002-agents-to-root.md, docs/specs/40_workspace/vasquez/HANDOFF-003-agents-to-root.md).

Fixed

  • Broken ../../templates/agents/README.md relative links → ../../agents/README.md resolves (SPEC-003, REQ-005).

Known issues

  • Mixed baseline: 10 tracked M files layer SPEC-002 + SPEC-003; committer verifies PASS-worthiness at commit time.
  • docs/briefs|specs/** old-path strings immutable by design.

[v0.3.0] — 2026-09-15

Added

  • 68 opencode agents vendored as reference-only templates + execution_mode: single | multi-subagents (SPEC-001-agent-templates; see docs/specs/30_delivery/RELEASE_NOTES.md v0.3.0-templates entry — old-path strings preserved as history).
  • MANDATORY LOAD ORDER enforced in plugin + all 9 stage skills: skill(stage) + read(agents/<domain>/<agent>.md) BEFORE any task/edit/bash, single AND multi-subagents. HARD STOP + retry N=2 → escalate montilla.
  • Execution modes frozen: single = direct (no task) + skill/template cite; multi-subagents = task(general) max 2 parallel with read orders in prompt (general-purpose default until agents natively registered).
  • 68 agent templates: adapter when run → REQUIRED inside frame-ship + portable note fixed; dispatched ONE template read fully, rest path-cites.
  • Gate + handoff verification: Load Evidence section in gate-report.md, DoD + HANDOFF.md fail without skill/template/mode/packet cites.