You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
resolve-frontmatter.sh fails with a "precondition violated" error whenever the branch manifest is absent. The manifest is created exclusively as a side effect of the get-session-context skill, and consumer skills frame the invocation as a data lookup ("use get-session-context to obtain project_slug and artifact_base_dir"). When the agent has already read those values from .agents/preferences.yaml, the lookup framing makes the call appear redundant, the agent skips it, the manifest never gets written, and the next artifact-writing operation fails.
The structural cause is an asymmetry. Derivation logic lives in a Zero-Bash skill that only main agents can invoke. Consumers include subagents and bash scripts (resolve-frontmatter.sh) that cannot invoke skills. The manifest exists to bridge that gap, and the side-effect mandate exists to keep the bridge populated. Both are workarounds for putting the derivation in a place not every caller can reach.
Context
The get-session-context skill is at packages/agents/content/skills/get-session-context/SKILL.md. It both returns session metadata and persists the branch manifest as a side effect.
The dependent script is at packages/agents/content/scripts/resolve-frontmatter.sh.
The manifest schema and the side-effect mandate are documented in packages/agents/content/skills/_data/artifact-conventions.md § Subagent dispatch precondition.
Every value the manifest carries is mechanically derivable from the current branch name plus the merged contents of .agents/preferences.yaml and ~/.agents/preferences.yaml. No field requires agent reasoning.
The agents package already runs non-trivial skill logic through a bundle pattern. scripts/bundle-skill-helpers.ts builds TypeScript entries in src/<skill>/ into self-contained .mjs files under content/skills/<skill>/, using esbuild to inline workspace and node_modules dependencies. Three skills already use this pattern: kb-add, kb-retrieve, and update-jira-ticket.
The newer YAML parser (yaml 2.9.0, eemeli's package) is already used by @codeassembly/kb-core for frontmatter parsing and document-AST manipulation. The agents package currently uses the older js-yaml; this work introduces eemeli yaml as a direct dependency.
The preferences shape has a JSON schema at packages/agents/schemas/preferences.json, and a schema validator is already a devDependency (@hyperjump/json-schema).
The canonical ticket-ID extraction contract lives in _data/ticket-id-extraction.md and is currently implemented in bash at packages/agents/content/scripts/get-ticket-id.sh. The TS deriver will reimplement the contract in TypeScript with its own tests. Both implementations conform to the same documented spec; consolidating them is out of scope.
Move the derivation contract into a TypeScript helper bundled via the existing skill-helper pipeline, and retire the asymmetry that made the side-effect mandate necessary.
Add src/derive-session-context/ containing the TypeScript entry point, pure derivation logic, an eemeli-yaml-based preferences reader that validates against schemas/preferences.json, a TypeScript implementation of the ticket-ID extraction contract per _data/ticket-id-extraction.md, and vitest unit tests covering every manifest edge case documented in the current get-session-context skill.
Register the new entry in bundle-skill-helpers.ts so the build produces content/skills/derive-session-context/derive-session-context.mjs. The bundled .mjs is self-contained and runs on stock Node 24+ with no monorepo packages required at runtime.
Add eemeli yaml as a direct dependency of @codeassembly/agents (already transitive via kb-core).
Modify resolve-frontmatter.sh to invoke the bundled deriver on cache miss instead of failing. The manifest remains the fast path; failure to find it becomes a recovery rather than a hard stop.
Deprecate and remove the get-session-context skill. Update every consumer skill's step-1 instruction to invoke the bundled deriver (or read the resulting manifest) instead. Once no consumers reference the skill, remove the skill file.
Rewrite artifact-conventions.md § Subagent dispatch precondition to describe the new architecture: Any caller writes the manifest on demand; no dispatch-time precondition exists.
The outcome is a single derivation implementation, callable identically by main agents, subagents, and shell scripts. The side-effect mandate goes away because no caller depends on another caller having run.
Acceptance criteria
src/derive-session-context/ exists with TypeScript source covering: an eemeli-yaml-based preferences reader (validating against schemas/preferences.json), a TS implementation of the ticket-ID extraction contract from _data/ticket-id-extraction.md, and a manifest composer. Vitest unit tests cover every manifest edge case documented in get-session-context/SKILL.md (Jira-style, bare-numeric with # prefix, bare-numeric with Jira-style prefix, no ticket, custom artifact paths, sub-ticket suffix, author-prefixed lowercase).
The deriver writes the manifest at the canonical path and emits the same JSON to stdout, matching the existing manifest schema.
The new entry is registered in bundle-skill-helpers.ts; a smoke-test invocation is registered in smoke-test-skill-helpers.ts; the build produces a working .mjs under content/skills/derive-session-context/.
eemeli yaml is added as a direct dependency of @codeassembly/agents.
resolve-frontmatter.sh invokes the bundled deriver on cache miss; the precondition error path is removed.
Every consumer skill's step-1 instruction is updated to invoke the bundled deriver or read the manifest directly.
The get-session-context skill file is removed; no references to it remain in skill files, _data/ docs, or other agents content.
artifact-conventions.md § Subagent dispatch precondition is rewritten to describe the new architecture.
New and modified behavior in this change is covered by tests (vitest unit tests for the deriver and preferences reader; smoke test for the bundle).
Documentation, help text, and usage examples for get-session-context are removed; no orphan references remain.
Problem
resolve-frontmatter.shfails with a "precondition violated" error whenever the branch manifest is absent. The manifest is created exclusively as a side effect of theget-session-contextskill, and consumer skills frame the invocation as a data lookup ("useget-session-contextto obtainproject_slugandartifact_base_dir"). When the agent has already read those values from.agents/preferences.yaml, the lookup framing makes the call appear redundant, the agent skips it, the manifest never gets written, and the next artifact-writing operation fails.The structural cause is an asymmetry. Derivation logic lives in a Zero-Bash skill that only main agents can invoke. Consumers include subagents and bash scripts (
resolve-frontmatter.sh) that cannot invoke skills. The manifest exists to bridge that gap, and the side-effect mandate exists to keep the bridge populated. Both are workarounds for putting the derivation in a place not every caller can reach.Context
get-session-contextskill is atpackages/agents/content/skills/get-session-context/SKILL.md. It both returns session metadata and persists the branch manifest as a side effect.packages/agents/content/scripts/resolve-frontmatter.sh.packages/agents/content/skills/_data/artifact-conventions.md§ Subagent dispatch precondition..agents/preferences.yamland~/.agents/preferences.yaml. No field requires agent reasoning.scripts/bundle-skill-helpers.tsbuilds TypeScript entries insrc/<skill>/into self-contained.mjsfiles undercontent/skills/<skill>/, using esbuild to inline workspace and node_modules dependencies. Three skills already use this pattern:kb-add,kb-retrieve, andupdate-jira-ticket.yaml2.9.0, eemeli's package) is already used by@codeassembly/kb-corefor frontmatter parsing and document-AST manipulation. The agents package currently uses the olderjs-yaml; this work introduces eemeliyamlas a direct dependency.packages/agents/schemas/preferences.json, and a schema validator is already a devDependency (@hyperjump/json-schema)._data/ticket-id-extraction.mdand is currently implemented in bash atpackages/agents/content/scripts/get-ticket-id.sh. The TS deriver will reimplement the contract in TypeScript with its own tests. Both implementations conform to the same documented spec; consolidating them is out of scope.align-ticket-with-implementation,condense-branch,create-devlog,create-pr(andcreate-gh-pr/create-bitbucket-pr),create-ticket,design-and-plan,find-orchestration-savings,merge-pr,orchestrate,plan,plan-orchestrable-steps,refine-plan,respond-to-review,review-branch,review-pr,save-artifact,save-plan,summarize-change,summarize-chat,wrap-up.Proposed solution
Move the derivation contract into a TypeScript helper bundled via the existing skill-helper pipeline, and retire the asymmetry that made the side-effect mandate necessary.
Add
src/derive-session-context/containing the TypeScript entry point, pure derivation logic, an eemeli-yaml-based preferences reader that validates againstschemas/preferences.json, a TypeScript implementation of the ticket-ID extraction contract per_data/ticket-id-extraction.md, and vitest unit tests covering every manifest edge case documented in the currentget-session-contextskill.Register the new entry in
bundle-skill-helpers.tsso the build producescontent/skills/derive-session-context/derive-session-context.mjs. The bundled.mjsis self-contained and runs on stock Node 24+ with no monorepo packages required at runtime.Add eemeli
yamlas a direct dependency of@codeassembly/agents(already transitive viakb-core).Modify
resolve-frontmatter.shto invoke the bundled deriver on cache miss instead of failing. The manifest remains the fast path; failure to find it becomes a recovery rather than a hard stop.Deprecate and remove the
get-session-contextskill. Update every consumer skill's step-1 instruction to invoke the bundled deriver (or read the resulting manifest) instead. Once no consumers reference the skill, remove the skill file.Rewrite
artifact-conventions.md§ Subagent dispatch precondition to describe the new architecture: Any caller writes the manifest on demand; no dispatch-time precondition exists.The outcome is a single derivation implementation, callable identically by main agents, subagents, and shell scripts. The side-effect mandate goes away because no caller depends on another caller having run.
Acceptance criteria
src/derive-session-context/exists with TypeScript source covering: an eemeli-yaml-based preferences reader (validating againstschemas/preferences.json), a TS implementation of the ticket-ID extraction contract from_data/ticket-id-extraction.md, and a manifest composer. Vitest unit tests cover every manifest edge case documented inget-session-context/SKILL.md(Jira-style, bare-numeric with#prefix, bare-numeric with Jira-style prefix, no ticket, custom artifact paths, sub-ticket suffix, author-prefixed lowercase).bundle-skill-helpers.ts; a smoke-test invocation is registered insmoke-test-skill-helpers.ts; the build produces a working.mjsundercontent/skills/derive-session-context/.yamlis added as a direct dependency of@codeassembly/agents.resolve-frontmatter.shinvokes the bundled deriver on cache miss; the precondition error path is removed.get-session-contextskill file is removed; no references to it remain in skill files,_data/docs, or other agents content.artifact-conventions.md§ Subagent dispatch precondition is rewritten to describe the new architecture.get-session-contextare removed; no orphan references remain.