Skip to content

docs(instructions): plan the architect brief against the single-package tree - #1677

Draft
claude[bot] wants to merge 2 commits into
mainfrom
claude/issue-1518-architect-brief-single-package
Draft

docs(instructions): plan the architect brief against the single-package tree#1677
claude[bot] wants to merge 2 commits into
mainfrom
claude/issue-1518-architect-brief-single-package

Conversation

@claude

@claude claude Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Description

.github/instructions/architect.md told every future architect agent to plan into a workspace this repo does not have, and it did so in three places of increasing force:

Where What it said Force
The worked "Recruiting System" example nine files under packages/hr/src/ illustrative
## Dependency Management Rules a crm / products / finance layering, stated as fact standing rule
## Output Format a package heading on every plan emitted mandatory ("Always start your response with…")

The file also contradicted itself, which is worse than either consistent answer: the same output template whose heading demanded a package filled its table rows with the single-package form. An agent reading it had to pick one and had nothing to pick with.

Maintainer ruling on #1518 (decision batch 21, 2026-09-03, ledger objectstack#12708): Option A — this brief describes THIS workspace. No option was chosen here; this is execution only.

Type of Change

  • Documentation update

Related Issues

Fixes #1518
Related to #1233 (the guard this change retires an entry from), #855 (the same class of defect, fixed once in AGENTS.md)

Changes Made

  • Deleted ## Dependency Management Rules in full.
  • Deleted the package heading from the mandatory ## Output Format template.
  • Re-mapped the worked example onto the real single-package tree.
  • Dropped the artifact kinds this repo has no home for, rather than re-prefixing them.
  • Deleted the architect.md entry from PENDING_PACKAGES_REFS in test/docs-src-tree-paths.test.tsrequired in this same PR, see below.

The re-map, row by row

Every surviving row keeps its original text. No row was invented to replace a deleted one.

Step Was Now Why
1 Data packages/hr/src/candidate.object.ts (+2 more) src/objects/candidate.object.ts (+2 more) 18 real *.object.ts live there
2 Automation …/application.mask.ts (Auto-number) row deleted see below
2 Automation …/application.workflow.ts src/flows/application-rejected.flow.ts 23 real *.flow.ts live there
3 UI …/recruiting.view.ts (Kanban) src/views/application.view.ts (Kanban) 14 real *.view.ts live there
3 UI …/approval.flow.ts moved to Step 2, src/flows/offer-approval.flow.ts a .flow.ts is not a screen; Step 3 is headed "Identify the screens"
4 Security …/roles.ts src/profiles/hiring-manager.profile.ts 7 real *.profile.ts live there
4 Security …/candidate.rls.ts src/sharing/candidate.sharing.ts 4 real *.sharing.ts live there

The auto-number row is deleted, not re-pointed. Auto-numbering is a field in this repo, not a file kind:

$ grep -rn 'Field.autonumber' src/ | wc -l
35

It lives inside the Step 1 object file (src/objects/case.object.ts:62, contract.object.ts:49, …), so it has no plan destination of its own. Re-pointing it at src/masks/ would only have traded one absent path for another — which is the defect, not the fix.

The five homeless kinds are gone from the file:

$ find src -name '*.mask.ts' -o -name '*.workflow.ts' -o -name '*.rls.ts' \
       -o -name '*.role.ts' -o -name '*.permission.ts' | wc -l
0

One judgement call, called out for review

The ruling notes that "the file's own table rows already use the single-package form". They do — but src/foo.object.ts is not a real path either: nothing lives directly under src/ (find src -maxdepth 1 -type f returns 0), every artefact sits one directory down. Leaving those rows would have re-created, inside the fixed file, the exact inconsistency this change exists to remove — the example above them now says src/objects/….

So the output template's rows moved with the example: src/objects/foo.object.ts, src/objects/foo.hook.ts (src/hooks/ is a re-export barrel, not their home — all 17 real *.hook.ts are in src/objects/) and src/pages/foo.page.ts. This is the one edit not literally enumerated in the ruling; it is a three-line revert if you disagree.

The guard entry — why it had to be in this PR, and proof it bites both ways

test/docs-src-tree-paths.test.ts pins the brief set under an equality, so it goes red in both directions. That was tested, not reasoned about — each leg mutated on disk, run, then restored and the restore proved by blob hash against HEAD.

Leg A — file fixed, PENDING_PACKAGES_REFS entry left in place:

AssertionError: the set of briefs naming `packages/…` changed:
  … expected [] to deeply equal [ '.github/instructions/architect.md' ]
 Tests  1 failed | 27 passed (28)

Leg B — entry deleted, architect.md reverted to its state on origin/main:

AssertionError: the set of briefs naming `packages/…` changed:
  .github/instructions/architect.md: packages/hr/src/candidate.object.ts, …
  … expected [ '.github/instructions/architect.md' ] to deeply equal []
 Tests  1 failed | 27 passed (28)

Restores verified: git diff HEAD empty and blob hash identical to the HEAD blob on both legs (brief 3506a350, guard e7ccc70e).

The list is now empty, which is the finished state and not a disabled one — the equality still fails the day any brief picks the retired layout back up. Only the comment above the constant changed with it; no assertion and no test name was touched.

The other five briefs were checked and are clean, so nothing else was owed here:

$ grep -rn 'packages/' .github/instructions/
(no output)

Testing

  • Unit tests pass — pnpm verify exit 0, the full chain
  • Linting passes
  • Build succeeds
  • New tests added — not applicable, and deliberately so: this deletes an entry from an existing guard. No new gate, no new test file (AGENTS.md, "Do not build platform-level tooling here").
> pnpm validate && pnpm typecheck && pnpm lint && pnpm lint:i18n-gate
  && pnpm hygiene && pnpm hygiene:tokens && pnpm build && pnpm test

  ✓ Validation passed (1522ms)
  ✓ i18n lint gate: 0 `i18n/missing-*` issues
  ✓ source hygiene clean
  ✓ source token ratchet clean
  ✓ Build complete (2045ms)
 Test Files  161 passed (161)
      Tests  3402 passed | 1 skipped (3403)

Run on df41dbba. The token ratchet is unmoved, as expected — it measures src/** and nothing here is under src/.

Checklist

Merge posture

.github/instructions/** is treated as AGENTS.md-class (2026-08-25 grading on #1233). This PR is therefore a draft, with no auto-merge and no merge queue, and it has not been approved. It is for the maintainer to merge by hand.

CI triage, 2026-09-06 — what was red, why, and what fixed it

Red: Check Changeset, and nothing else. Read from the check-runs API for head df41dbba (the combined-status endpoint on this repo only ever returns Vercel, which is why this needed the other endpoint): Build and Test (22.x), Quality Checks, Playwright, link-check, CodeQL, Analyze Code (javascript) and Label Pull Request were all success; Check Changeset appears twice — run 34025202120 failure, run 34025210461 skipped.

The failing job's log, verbatim:

##[error]This PR adds no changeset. Run 'pnpm changeset' and commit the generated .changeset/*.md file, or apply the 'skip-changeset' label if this change genuinely ships nothing (pure CI/docs chores).
##[error]Process completed with exit code 1.

Cause — a label race at PR-open, not a stale base. changeset-check.yml gates the job on if: !contains(github.event.pull_request.labels.*.name, 'skip-changeset'), and that is evaluated against the payload of the event that started the run:

Time (UTC) Event
09:37:57 PR opened
09:38:03 Check Changeset starts from the opened payload — no labels on it yet
09:38:08 it fails
09:38:10 skip-changeset applied
09:38:19 the labeled re-run fires and skips, correctly

So this PR has carried that red since 11 seconds after it was opened — nothing turned red later. A workflow run is never re-evaluated, so the failed run stays bound to df41dbba for ever, and re-running it would only replay the same label-less payload.

Two hypotheses tested and killed before acting on either.

  1. Stale base. Real — main had moved 23 commits past this PR's base f4f7dfe7 — but not the red. Merged in and re-measured: pnpm verify exit 0, and pnpm test:coverage (the form CI actually runs) exit 0 as well.
  2. The equality pin flipping the other way. PENDING_PACKAGES_REFS is an equality assertion, so a packages/… mention re-introduced into any brief would fail it against the now-empty expected set. Measured: main has touched neither .github/instructions/** nor test/docs-src-tree-paths.test.ts since this branch was cut, and on today's main architect.md is still the only brief naming packages/… — the one this PR removes. The pin passes in both trees. No entry was added back, and no assertion was relaxed.

Fix: merge main into the branch (commit fa238330). That refreshes the base and gives the PR a head whose Check Changeset run is evaluated with skip-changeset already applied. No rebase, no amend, no force-push; the PR's own diff is unchanged — still .github/instructions/architect.md plus the one constant in test/docs-src-tree-paths.test.ts.

Gate re-run on fa238330, exit code captured before any pipe:

$ pnpm verify    # validate, typecheck, lint, lint:i18n-gate, hygiene, hygiene:tokens, build, test
 Test Files  161 passed (161)
      Tests  3410 passed | 1 skipped (3411)
PNPM VERIFY EXIT=0

pnpm test:coverage also exit 0 — All files 95.93 | 84.77 | 95.87 | 99.36. The E2E (Playwright) and link-check workflows are not part of pnpm verify; they re-run in CI on this head.

Posture unchanged: still a draft, no auto-merge, no merge queue, no approval. The maintainer merges it by hand.


Generated by Claude Code

…ge tree

`architect.md` told every future architect agent to plan into a workspace this
repo does not have, and it did so in three places of increasing force. The
worked "Recruiting System" example routed nine files under `packages/hr/src/`.
The standing "Dependency Management Rules" named a `crm` / `products` /
`finance` layering as fact. And the MANDATORY Output Format — "Always start
your response with the Architecture Plan" — headed EVERY plan the architect
emits with a package heading.

The file also contradicted itself, which is worse than either consistent
answer: the same output template whose heading demanded a package filled its
table rows with the single-package form. An agent reading it had to pick one
and had nothing to pick with.

Ruled scope: this brief describes THIS workspace. So the dependency rules
section is deleted outright (its layering names three directories that do not
exist, and its third item is wrong on its own terms — `@objectstack/spec` is a
plain `dependency` here, not a dev/peer one), the package heading is deleted
from the output template, and the example is re-mapped onto the real tree:
objects to `src/objects/`, automation to `src/flows/`, the pipeline board to
`src/views/`, the actor to `src/profiles/` and row-level access to
`src/sharing/`.

Artifact kinds with no home here are dropped rather than re-prefixed —
`find src -name '*.mask.ts' -o -name '*.workflow.ts' -o -name '*.rls.ts' -o
-name '*.role.ts' -o -name '*.permission.ts'` returns nothing, so a faithful
"strip the prefix" rewrite would only have traded one absent path for another.
The auto-number row is deleted, not re-pointed: auto-numbering is a FIELD in
this repo (`Field.autonumber`, 35 occurrences across `src/objects/*.object.ts`)
and has no plan destination of its own. The approval row keeps its text and
moves from the UI step to the automation step, because a `.flow.ts` is not a
screen. No row was invented to replace a deleted one.

The output template's rows move with it: `src/foo.object.ts` is not a real path
either — nothing lives directly under `src/`, every artefact sits one directory
down — so they now read `src/objects/foo.object.ts`, `src/objects/foo.hook.ts`
(`src/hooks/` is a re-export barrel, not their home) and `src/pages/foo.page.ts`.
Leaving them would have re-created inside the fixed file the very
inconsistency this change exists to remove.

The guard's `PENDING_PACKAGES_REFS` entry goes in the same commit because it
must: the assertion is an equality, so fixing the file without deleting the
entry is red, and deleting the entry without fixing the file is red. The list
is now empty, which is the finished state and not a disabled one — the equality
still fails the day any brief picks the retired layout back up. Only the
comment above the constant changed with it; no assertion and no test name was
touched.

Co-authored-by: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
hotcrm Ignored Ignored Sep 6, 2026 2:45pm UTC

Request Review

Two reasons, neither of which changes this PR's own scope.

1. The head commit carries a permanently-failed `Check Changeset` run. That
   run started 6s after the PR was opened; the `skip-changeset` label landed
   2s after it had already failed, so the workflow's
   `if: !contains(labels, 'skip-changeset')` guard evaluated a payload that
   did not yet carry the label. The `labeled` re-run seconds later skipped
   correctly, but the failed run stays attached to that head for ever and no
   event re-evaluates it. A new head is the only way to clear it without a
   rebase or a force-push.

2. The base had moved 23 commits since the PR was opened, so the last green
   `Build and Test` measured a base that no longer exists.

The diff against main is unchanged: `.github/instructions/architect.md` plus
the `PENDING_PACKAGES_REFS` constant in `test/docs-src-tree-paths.test.ts`.

Co-authored-by: Claude
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd CI plumbing and the verification pipeline skip-changeset PR ships nothing to users (pure CI/docs chore) — changeset gate waived

Projects

None yet

1 participant