🔧 chore: the working agreement lives in the repository, with a session-start hook and the central OpenSpec store - #11
Merged
Conversation
openspec/config.yaml points at eQuantic/equantic-specs, where the core workstream keeps its specs and changes, and says nothing else. `openspec init --tools claude,agents` installed the /opsx commands and the skills for Claude Code and for the agents that read .agents/. The CLI is pinned by tools/openspec/package-lock.json to the store's 1.14.0, the first whose apply, started in a repository that points at a store, edits that repository.
…ion is written .claude/settings.json turns off every attribution Claude Code adds (the commit trailer, the pull request footer and the session link), keeps OpenSpec's telemetry off, lets a session write to ../equantic-specs, and registers .claude/hooks/session-start.sh. In a cloud container the hook commits as Edgar Mesquita <edgar@equantic.tech> with commit and tag signing off, installs the pinned OpenSpec CLI, clones and registers the store beside the repository, installs the .NET SDK 10.0.401 after checking its SHA-256, and starts Docker. On a laptop it only puts the pinned OpenSpec CLI on the session's PATH and checks that the store is registered. What it cannot prepare it tells the person, and the session still starts.
…'s conventions are checked The openspec job fails when openspec/config.yaml says more than `store: equantic-specs`, when a planning folder appears here, or when the lockfile pins a CLI older than 1.14.0. The session-start job runs the hook the way a fresh cloud container would, with a hostile global git config, and the way a laptop would, and checks each of its promises, a refused SDK archive and an unreachable store included. The Pull request workflow checks the branch, the title and the body. Each check proves it still fails where it should.
…d AGENTS.md The same section in both files: branches, commits and their attribution, the owner's identity, the issue behind every change, the pull request, the Copilot review loop and the squash merge, CI on eQuantic Space while GitHub Actions has no credits, English in everything committed, the docs and the ledger in the same pull request, OpenSpec in the central store, and what a session starts from. WorkflowSectionTests fails when the two copies differ, naming the first line that does. The pull request template, docs/LEDGER.md and the README follow.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The OpenSpec validator accepts malformed quoting, and several session preparation failures are silently reported as successes.
Review effort: Balanced
Findings: 3
Open (3)
What changed in this PR
Establishes repository-wide workflow guidance, central OpenSpec integration, session initialization, and CI enforcement.
Changes:
- Adds synchronized working agreements and OpenSpec tooling.
- Adds session-start automation for Git, .NET, Docker, and OpenSpec.
- Adds CI checks, self-tests, documentation, and PR conventions.
| File | Description |
|---|---|
.gitignore |
Ignores installed Node dependencies. |
.github/pull_request_template.md |
Adds the repository PR template. |
.github/workflows/ci.yml |
Adds OpenSpec and session-hook jobs. |
.github/workflows/pull-request.yml |
Enforces PR conventions. |
.claude/settings.json |
Registers the hook and disables attribution. |
.claude/hooks/session-start.sh |
Prepares cloud and local sessions. |
.claude/commands/opsx/apply.md |
Adds the OpenSpec apply command. |
.claude/commands/opsx/archive.md |
Adds the archive command. |
.claude/commands/opsx/explore.md |
Adds the exploration command. |
.claude/commands/opsx/propose.md |
Adds the proposal command. |
.claude/commands/opsx/sync.md |
Adds the specification sync command. |
.claude/commands/opsx/update.md |
Adds the change update command. |
.claude/skills/openspec-apply-change/SKILL.md |
Defines Claude apply guidance. |
.claude/skills/openspec-archive-change/SKILL.md |
Defines Claude archive guidance. |
.claude/skills/openspec-explore/SKILL.md |
Defines Claude exploration guidance. |
.claude/skills/openspec-propose/SKILL.md |
Defines Claude proposal guidance. |
.claude/skills/openspec-sync-specs/SKILL.md |
Defines Claude sync guidance. |
.claude/skills/openspec-update-change/SKILL.md |
Defines Claude update guidance. |
.agents/skills/.openspec-target |
Selects the agents OpenSpec target. |
.agents/skills/openspec-apply-change/SKILL.md |
Defines agent apply guidance. |
.agents/skills/openspec-archive-change/SKILL.md |
Defines agent archive guidance. |
.agents/skills/openspec-explore/SKILL.md |
Defines agent exploration guidance. |
.agents/skills/openspec-propose/SKILL.md |
Defines agent proposal guidance. |
.agents/skills/openspec-sync-specs/SKILL.md |
Defines agent sync guidance. |
.agents/skills/openspec-update-change/SKILL.md |
Defines agent update guidance. |
AGENTS.md |
Adds the agent working agreement. |
CLAUDE.md |
Adds project and workflow guidance. |
README.md |
Documents CI and contribution workflows. |
docs/LEDGER.md |
Records repository history. |
openspec/config.yaml |
Points to the central store. |
scripts/check-openspec.sh |
Validates the OpenSpec pointer. |
scripts/check-pull-request.sh |
Validates PR conventions. |
scripts/check-session-start.sh |
Exercises session-hook behavior. |
tests/eQuantic.Payment.Tests/WorkflowSectionTests.cs |
Guards workflow-section synchronization. |
tools/openspec/package.json |
Declares the pinned OpenSpec CLI. |
tools/openspec/package-lock.json |
Locks OpenSpec dependencies. |
Files not reviewed (1)
- tools/openspec/package-lock.json: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…or the env file could not be prepared
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
The extensive session-bootstrap and workflow automation warrants final human validation despite no specific defect being identified.
Review effort: Balanced
Findings: None
Resolved since last review (3)
Files not reviewed (1)
- tools/openspec/package-lock.json: Generated file
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
## Workflowsection, the same text inCLAUDE.mdandAGENTS.md:<type>/<slug>branches and nothing straight tomain; commits in English asemoji type: description, with no co-authorship or attribution; the owner's identity; a typed issue on the board (#16) behind every change, closed by its pull request; Copilot's review until a round brings nothing new, then the squash merge on green CI, under the pull request's title; CI on eQuantic Space (eqs runs) while GitHub Actions has no credits; English in everything committed and posted, Portuguese only in the chat; the docs anddocs/LEDGER.mdin the same pull request; OpenSpec in the central store; what a session starts from.WorkflowSectionTestsfails when the two copies differ, naming the first line that does.coreworkstream.openspec/config.yamlholdsstore: equantic-specsand nothing else,openspec init --tools claude,agentsgenerated.claude/commands/opsx/,.claude/skills/and.agents/skills/, and the CLI is pinned bytools/openspec/package-lock.jsonto the store's 1.14.0 (the store's own lockfile, renamed), with telemetry off. This carries everything 🔧 chore: specs and changes live in the central OpenSpec store #6 did, which can close once this merges..claude/settings.jsonsetsattributionto{ "commit": "", "pr": "", "sessionUrl": false }, so Claude Code adds no commit trailer, no pull request footer and no session link..claude/hooks/session-start.sh, registered in.claude/settings.json:~/.dotnetonce its SHA-256 matches the pin (linux-x64 and linux-arm64); Docker startedtools/openspecand put on the session's PATH, and a check that the store is registered; the identity, the signing, the SDKs, Docker and the store registry are left as they areopenspecfails when the pointer says more thanstore: equantic-specs(unquoted, or in balanced quotes), whenopenspec/specsoropenspec/changesappears here, or when the lockfile pins a CLI older than 1.14.0; it installs the pinned CLI from its lockfile. The store's own CI runsopenspec validate --all --stricton every push, and this repository's CI cannot read the private store.session-startruns the hook the way a fresh cloud container would, with a hostile global git config, and the way a laptop would, and checks each promise, a refused SDK archive, an unreachable store and a store checkout that cannot take the identity included.Pull requestworkflow checks the branch, the title and the body, and runs again when the title or the body is edited.docs/LEDGER.mdwith the history so far, one line per event, and the README (the new CI jobs, a Contributing section).Why
Closes #10.
A rule that is not in the repository does not survive the next session: a cloud container starts with another git identity, signs commits with a key that is not the owner's, has no .NET SDK, and knows nothing of the flow. And every eQuantic product now plans in eQuantic/equantic-specs (eQuantic/equantic-specs#1), which this repository did not point at yet.
No OpenSpec change: nothing a consumer of the packages observes moves (this is tooling, docs and CI), and the store's rules ask no proposal for that.
Proof
dotnet build -c Release, 0 warnings, 0 errors;dotnet test --no-build -c Release, 93 of 93, 1 of them new.WorkflowSectionTestsfails on a one-line edit toAGENTS.md, namingCLAUDE.md:32andAGENTS.md:15, and on aCLAUDE.mdwith no Workflow section.dotnet packstill puts the README and the icon in all 9 packages.scripts/check-openspec.sh: its self-test passes its 13 cases, unbalanced quotes and a value glued to the colon among the failures; the check passes on this tree and fails with anopenspec/changes/folder; a mutant whose check never fails is refused by the self-test.scripts/check-pull-request.sh: its self-test passes its 19 cases in the C, C.UTF-8 and en_US.UTF-8 locales, and the branches, titles and bodies of 🔧 chore: specs and changes live in the central OpenSpec store #6 and ✨ feat: saved cards charged with the customer away, and boleto, on Stripe #9 pass it. On this pull request it already bit: the tool that opened it appended a generated-by footer with a session link, thePull requestworkflow failed on it, and it passed once the footer was removed. The footer's wording is now one of its cases.scripts/check-session-start.sh: all 28 of its checks pass, locally in about 30 s and on GitHub Actions in 25 s. Two mutant hooks fail it: one that skips the identity ("after the hook, a commit still fails"), and one that stays silent when the store's checkout cannot take the identity.dotnet --versionanswers 10.0.401 in the repository), putopenspec1.14.0 on PATH, registered the store and started Docker, and said nothing to the person. Withdockeroff its PATH, or with an env file it cannot write, it tells the person so.openspec list --specs, run in the repository, lists the store's specs.https://builds.dotnet.microsoft.com/dotnet/release-metadata/10.0/releases.json.🔧 choreand releases nothing.