A coding agent receives a precise prompt: refresh authentication sessions without interrupting active users. It reads the repository, finds the right abstractions, writes clean code, and passes every trusted test.
It also changes shared authentication middleware, migrates a database table, and edits deployment configuration.
The code may be technically correct. The tests may be green. The change can still exceed the scope anybody approved.
That is the gap EngineeringSpec is trying to make explicit. Better prompts help express intent. More context helps an agent understand a system. Stronger validation helps determine whether the result works. None of those, by itself, answers what the agent was allowed to change.
What does the agent know?
Did the resulting change work?
What was the agent allowed to change?
These controls complement each other, but they are not interchangeable. A prompt is not an approval record. Repository access is not write authority. A successful analysis or test run does not widen scope.
Permission should be reviewable data
EngineeringSpec represents an engineering change as a versioned contract in the repository. The contract names the intended targets, path policies, constraints, technical obligations, verifier identities, and stop conditions. A human can review that boundary as a normal Git change before an implementation agent consumes it.
The authority comes from the exact approved contract in immutable, reviewed Git history—the trusted base—not from a prompt, an unmerged workspace document, or whatever happens to be present at the branch head. An agent may read broadly when that is necessary for correctness, while its write authority remains bounded to the policy-bearing paths the contract grants.
This matters because implementation discovers things. If the approved boundary turns out to be too narrow, the safe answer is not to reinterpret the task generously. It is to stop and make the wider decision visible.
The RC17 agent workflow
The default workflow in EngineeringSpec 0.1.0-rc.17 is deliberately small:
engineeringspec next
engineeringspec work ES-session-refresh
# agent implements
engineeringspec finish ES-session-refresh
next describes the current lifecycle action. work loads one exact approved contract from the trusted base and returns the pre-code authority envelope. After implementation and separately trusted repository checks, finish evaluates the complete Git state and can prepare the exact monotonic lifecycle close when the authority has been spent correctly.
The compact next PermissionTicket uses the actual RC17 fields permission, workflowState, currentChangeClassification, command, approvedIds, proposedIds, and blockers. It reports what the agent may do now, what the current diff is, and an executable diagnostic command when routing is blocked.
A valid pre-edit state
- permission
implementation- workflowState
implement- currentChangeClassification
none- approvedIds
ES-session-refresh- proposedIds
- none
- blockers
- none
The compact work PermissionTicket identifies result, permission, contractId, baseSha, and—when available—specRevision and semanticDigest. It preserves policy-bearing writablePaths and protectedPaths, along with constraints, verifier identities in verifiers, technicalContracts, and stopWhen. Verifier runner payloads are not exposed or executed.
In this fictional case, the ticket names contractId: ES-session-refresh and specRevision: 1. Its baseSha is the exact 40-character commit containing the reviewed approval—not a mutable branch name—and its semantic digest binds the contract content loaded from that base.
For an existing consumer that needs the previous full JSON reports and exit behavior, --verbose remains the compatibility path. The compact projection reduces parsing; it does not create a new source of permission.
Permission and classification are independent
The pre-edit ticket above is not contradictory:
permission = implementationandcurrentChangeClassification = nonecan coexist.
Permission comes from reviewed trusted-base authority. Classification describes the diff that currently exists. Before the first edit, there may be no changed paths to classify, even though a reviewed contract already grants implementation permission.
Later, the observed diff may classify as implementation. An exact approved-to-implemented contract transition beside the authorised implementation may classify as implementation_with_monotonic_close. A governance-only change can classify as contract_only. These are observations about the complete current change. Classification never grants or widens authority, and it is not a forecast of the lane an agent will eventually produce.
The inverse is important too: a diff can classify as implementation while the agent has no permission to create it. A successful command or a plausible classification does not retroactively authorise the work.
A bounded session-refresh change
Suppose the reviewed ES-session-refresh contract grants writes only under two surfaces:
Approved writes
- src/auth/session/**
- test/auth/session/**
Outside authority
- src/auth/middleware/**
- db/**
- infra/**
The agent is still free to read middleware, database, infrastructure, architecture, and tests when needed to understand the change. Reading for correctness does not silently turn those paths into writable surfaces.
If the implementation genuinely requires broader writes, the recovery path is explicit:
Stop → explain the blocker → obtain a separately reviewed authority amendment → continue from the new trusted base.
The amendment can change the contract, but it must be reviewed and merged as authority before dependent writes rely on it. A workspace edit that widens scope cannot approve itself.
One control loop, two views
The human-facing lifecycle is a six-stage control loop:
- Explore
- Propose
- Approve
- Implement
- Verify
- Close
Explore is read-only. Propose turns intent into a reviewable contract without granting implementation permission. Approve places the reviewed boundary on trusted history. Implement consumes that base-pinned authority. Verify combines separately trusted checks with complete-state routing. Close records the exact lifecycle transition after the evidence is reviewed.
next → work → finish is a lower-ceremony projection of that same lifecycle for an agent. It is not a second authorization mechanism. next does not approve work, work cannot trust a workspace contract, and finish cannot manufacture a valid close for an unauthorised diff.
What changed in RC17
RC17 changes the agent-facing projection, not the underlying authority model:
- compact
nextPermissionTickets by default; - compact, pre-code
workPermissionTickets by default; --verbosecompatibility for previous full reports and exit behavior;- executable blocker recovery for uncovered, denied, ambiguous, or missing-candidate routing;
- an explicit separation between permission and current-change classification;
- aligned guidance for coding agents and repository maintainers.
Trusted-base authority, multi-contract routing, finish semantics, and specification-runner inertness are unchanged. RC17 does not predict a future lane, execute declared verification runners, or make a compact ticket into a parallel approval system.
What verification can—and cannot—say
EngineeringSpec checks the complete Git state: committed, staged, unstaged, deleted, renamed, and untracked paths. Repository routing can identify paths selected for an approved contract, selected for another contract, denied, uncovered, or ambiguous. Governance and implementation classifications describe that complete state, including the exact monotonic close when present.
That answers whether the observed change fits the reviewed authority. It does not answer every engineering question.
Verification runners declared in a specification remain inert data. Teams run their tests, linters, security checks, review processes, and acceptance procedures separately. EngineeringSpec does not claim that a valid route proves software correctness, security, productivity, acceptable implementation quality, or successful checks.
The boundary is intentional: authority evidence and software-quality evidence should be clear enough to inspect separately, then review together.
No new control plane required
EngineeringSpec is an open, agent-neutral, Git-and-CI-oriented format with a CLI and reference implementation. It does not require an MCP server, ACP or hosted control plane, a specific coding agent, a context graph, or a telemetry service.
Those systems may be useful in some environments. They are not prerequisites and are not current EngineeringSpec features. The smallest useful setup is deliberately ordinary: a reviewed contract in Git, a coding agent that can consume the permission ticket, and repository checks that compare the resulting change with trusted authority.
What we do not know yet
We do not yet have evidence that EngineeringSpec makes coding agents faster, more productive, safer, or more correct.
The model is testable. That is different from having tested it with external adopters.
The public pilot uses paired tasks: a baseline condition and an EngineeringSpec condition receive the same task, same immutable base, same agent and model, same harness, same permissions, and same trusted checks. Time limits, acceptance criteria, and reviewer identity are also held constant.
The target is two to five external users or repositories and at least ten paired tasks where practical. Failed, slower, amended, onboarding-blocked, scope-violating, protocol-deviating, and inconclusive runs are retained rather than filtered away. Synthetic examples remain separate from observed evidence.
Any eventual result will describe the retained sample, its missing data, and its limitations. It will not establish causality or general adoption. A negative result—extra ceremony with no useful control benefit for a class of tasks—is useful evidence too.
Challenge the authority model
If you maintain a repository where coding agents do real work, we would value criticism more than agreement. Try one paired task. Tell us where the authority boundary is too rigid, too vague, or too expensive. Contribute negative results. Propose an alternative approach that preserves explicit review without slowing the inner loop to a crawl.
Install the exact release candidate:
npm install --save-exact @engineeringspec/cli@0.1.0-rc.17