Skip to content

🔧 chore: the working agreement lives in the repository, with a session-start hook and the central OpenSpec store - #11

Merged
edgarmesquita merged 8 commits into
mainfrom
chore/working-agreement
Oct 1, 2026
Merged

edgarmesquita merged 8 commits into
mainfrom
chore/working-agreement

Conversation

@edgarmesquita

@edgarmesquita edgarmesquita commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

What

  • The working agreement is a ## Workflow section, the same text in CLAUDE.md and AGENTS.md: <type>/<slug> branches and nothing straight to main; commits in English as emoji 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 and docs/LEDGER.md in the same pull request; OpenSpec in the central store; what a session starts from. WorkflowSectionTests fails when the two copies differ, naming the first line that does.
  • Planning in the central store, eQuantic/equantic-specs, as the core workstream. openspec/config.yaml holds store: equantic-specs and nothing else, openspec init --tools claude,agents generated .claude/commands/opsx/, .claude/skills/ and .agents/skills/, and the CLI is pinned by tools/openspec/package-lock.json to 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.
  • No attribution: .claude/settings.json sets attribution to { "commit": "", "pr": "", "sessionUrl": false }, so Claude Code adds no commit trailer, no pull request footer and no session link.
  • The session-start hook, .claude/hooks/session-start.sh, registered in .claude/settings.json:
    • in a cloud container: the owner's identity and commit and tag signing off in the repository's git config (and in the store's), the identity also exported to the session; the pinned OpenSpec CLI on PATH; the store cloned beside the repository over HTTPS and registered; the .NET SDK 10.0.401 installed in ~/.dotnet once its SHA-256 matches the pin (linux-x64 and linux-arm64); Docker started
    • on a laptop: only the pinned OpenSpec CLI, installed under tools/openspec and 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 are
    • it never blocks the session: what it prepared goes to the agent, and whatever it could not prepare (the identity in the repository or in the store's checkout, the CLI, the store, the SDK, Docker, an env file it cannot write) also goes to the person, with the command that fixes it
  • CI:
    • openspec fails when the pointer says more than store: equantic-specs (unquoted, or in balanced quotes), when openspec/specs or openspec/changes appears 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 runs openspec validate --all --strict on every push, and this repository's CI cannot read the private store.
    • session-start 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 promise, a refused SDK archive, an unreachable store and a store checkout that cannot take the identity included.
    • the Pull request workflow checks the branch, the title and the body, and runs again when the title or the body is edited.
    • every check runs its self-test first, which proves it still fails where it should.
  • Docs: the pull request template (What, Why with the issue and the OpenSpec change, Proof, a checklist), docs/LEDGER.md with 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

  • Build and tests: dotnet build -c Release, 0 warnings, 0 errors; dotnet test --no-build -c Release, 93 of 93, 1 of them new. WorkflowSectionTests fails on a one-line edit to AGENTS.md, naming CLAUDE.md:32 and AGENTS.md:15, and on a CLAUDE.md with no Workflow section. dotnet pack still 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 an openspec/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, the Pull request workflow 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.
  • The hook in a real cloud container (this session's): in 12 s it set the identity, installed the SDK (dotnet --version answers 10.0.401 in the repository), put openspec 1.14.0 on PATH, registered the store and started Docker, and said nothing to the person. With docker off 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.
  • The SDK pins: each SHA-256 was taken from a download of Microsoft's 10.0.401 archive whose SHA-512 matched https://builds.dotnet.microsoft.com/dotnet/release-metadata/10.0/releases.json.
  • shellcheck 0.11.0 is clean on the hook and the three scripts.
  • Copilot, round 1: three findings (a store identity failure and a missing Docker reported as notes, and a pointer with unbalanced quotes accepted), all fixed in f586727 and b27d8e8, each with a case in the checks above.
  • Release: squash-merged under this title, semantic-release reads 🔧 chore and releases nothing.

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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Medium severity

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.

Comment thread .claude/hooks/session-start.sh Outdated
Comment thread .claude/hooks/session-start.sh
Comment thread scripts/check-openspec.sh Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@edgarmesquita
edgarmesquita merged commit a56ac5c into main Oct 1, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The working agreement lives in the repository: the Workflow section, a session-start hook and the central OpenSpec store

3 participants