Support unnumbered issues in the document link recipe

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-02 17:29:55 -05:00
1 parent 74d0d3d945
commit 2d6e27f47e
9 files changed
+64 -16

No files matched your search

@@ -61,3 +61,15 @@ unchanged under permitted local execution: 906 assertions passed in the original
921-assertion attempt, and all 82 selected assertions passed in the permitted
retry, including every originally failed assertion. No new model calls or old verdict
changes are part of this follow-up.
Fresh native-PR review caught a supported edge case in that later recipe:
`issue.identifier` may be null. The recipe now uses the current issue ID in the
unprefixed UI route when no identifier exists. Provider-free tests cover both
null and absent identifiers, preserving the returned document key. Source review
confirms that the board resolves the loaded issue's actual company and preserves
the document hash; no agent-side company fetch is needed. This route logic also
corrects wrong prefixes, so the frozen candidate's `PAP` href is noncanonical,
not a proven broken link. No authenticated click replay or further model run was
made. The previous 4/5 review and local setup/timing failures remain retained;
current focused document/source/manifest/admission checks pass 56 assertions and
E2E typecheck passes. This correction still has no live qualification.
@@ -250,9 +250,13 @@ Starting points: [onboarding assets](../../server/src/onboarding-assets/),
[hiring skill and references](../../skills/paperclip-create-agent/),
[teams catalog](../../packages/teams-catalog/catalog/).
Dotta approved hiring implementation; it is ongoing in a separate branch from
master. The hiring work owns its skill/references, CEO/CoS assets and team
catalog. This qualification branch does not change those files.
Dotta approved hiring implementation in separate draft
[PR #14985](https://github.com/paperclipai/paperclip/pull/14985), branch
`codex/tiny-hiring-templates`, published source
`5b05d9dcf99b7b1e84510735ab04e336d669ee44`. The hiring work owns its
skill/references, CEO/CoS assets and team catalog. This branch does not change
those files; PR CI/review and live qualification remain separate from its unit
checks. [Prompt diffs and preserved scope](https://github.com/paperclipai/paperclip/blob/5b05d9dcf99b7b1e84510735ab04e336d669ee44/doc/plans/2026-10-02-hiring-template-prompt-diff.md).
The read-only audit found four onboarding CEO files (1,897 words), a 164-word
CoS manual, four role examples (coder 652, QA 619, UX 1,325, security 1,724 words),
@@ -268,7 +272,23 @@ review checklist would regenerate the removed operating policies.
product-required behavior rather than assuming every rule is redundant.
Custom and existing bundles and governance remain deliberate rollout boundaries.
Separate hiring PR/branch link and prompt diffs are pending.
Specialized Summarizer, Reflection Coach and Wiki Maintainer prompts remain
unchanged for separate product-contract review; optional Content Lead was already
tiny. The generic non-CEO fallback belongs to PR #14948. PR #14985 does not reduce
every shipped specialized agent.
Its explicit `hiring-templates` suite selects native local Codex and ACPX Claude
`hire-coder-template-reuse` cells: a real default CEO, explicitly requested
production hiring skill/coder reference, independently scored saved JSON
artifacts and session reuse. Outcome and source/read coverage are separate;
missing or redacted receipts do not prove no regression. The existing first-task
suite covers actual wizard CoS snapshot selection. A matched union qualification
will hold the reduced manual/shared/operational skill and native completion
guidance constant while restoring only historical hiring sources in baseline.
Two cells per variant, five expected provider turns each: four cells / 20 turns,
15 minutes each, no automatic retries or broader selection. Exact-source
credential-free admission and frozen refs are required before dispatch; no
hiring providers have run yet.
## 4. Fix repository context while retaining Paperclip configuration
@@ -448,7 +468,7 @@ will address them. Record intentional behavior explicitly rather than as a bug.
- F19: Original prompt-removal cohorts loaded Paperclip; OpenCode skill truncation omitted the late API recipe. The early repair fixed Claude in one paired trial. In the repaired original OpenCode assignment, Paperclip was first loaded only during disposition recovery after a local-file write. Shared legacy operational-skill delivery/selection needs review before more recipe expansion.
- F20: Explicit repaired OpenCode reads the early recipe/reference and saves a public document/revision, but hands off a code-formatted path rather than a clickable anchor. Baseline provides a clickable API URL, rejected by the UI-only oracle. Preserve both grades; clarify future clickable UI-link fixture and review the smallest link example separately.
- F22: Legacy operational skill mounting is already mandatory, but its discovery description omitted ordinary task/heartbeat work and document delivery. The approved narrow fix expands stock metadata selection and adds a real Markdown link example in the existing reference. Original + clarified-explicit OpenCode pairs both pass in both variants, so improvement causality is not established. Candidate loads the operational skill/reference before public delivery; baseline original writes locally first, then saves publicly in the same assignment. Original candidate copies the example PAP prefix into its link while baseline supplies a bare slug path; neither is scored by the original link-free oracle. No full-body injection or native-tool leakage. ACP Claude names-only metadata, custom ACP unsupported delivery, OpenClaw wrappers and Pi HOME differences remain distinct follow-ups.
- F23: The new original OpenCode candidate copies `/PAP/issues/RUN-1#document-context-integrity-output` from the literal example despite actual prefix RUN. It passes durable-document grading but has an incorrect-prefix handoff. Baseline original also lacks a clickable canonical link. Approved reference-only correction now derives the link from `issue.identifier` and the saved receipt key. Independent provider-free calibration checks two other prefixes, redirected keys and rejects a wrong-company link; 25 focused document/source tests, canonical metadata checks and E2E typecheck pass. This later source correction is not live-qualified by the preserved runs; no further paid rerun.
- F23: The new original OpenCode candidate copies `/PAP/issues/RUN-1#document-context-integrity-output` from the literal example despite actual prefix RUN. It passes durable-document grading but has an incorrect-prefix handoff. Baseline original also lacks a clickable canonical link. Approved reference-only correction now derives the link from `issue.identifier` and the saved receipt key. Independent provider-free calibration checks two other prefixes, redirected keys and rejects a wrong-company link; 25 focused document/source tests, canonical metadata checks and E2E typecheck pass. The recipe now also handles null/absent identifiers through the supported issue-ID route; fresh review caught the initial nullable edge. 56 focused checks pass. Source review shows the UI corrects wrong prefixes, so the frozen PAP href is noncanonical rather than proven broken. These later corrections are not live-qualified by the preserved runs; no further paid rerun.
- F21: Skill heading insertion shifted both generated capability inventories. General CI caught stale metadata after the frozen repair campaign’s narrower build admitted providers. Regenerate canonical derived files and require stale-manifest/inventory checks before future provider admission.
For each completed item, add the chosen behavior, changed paths, verification
@@ -171,7 +171,7 @@ The skill/reference inventory and eval cases are the only normative behavior sou
| skill:skills/paperclip/references/company-skills.md:notes:256 | optional_agent_tool | skills/paperclip/references/company-skills.md:256 |
| skill:skills/paperclip/references/issue-documents.md:issue-documents-through-the-api:1 | always_agent_tool | skills/paperclip/references/issue-documents.md:1 |
| skill:skills/paperclip/references/issue-documents.md:create-a-document:8 | always_agent_tool | skills/paperclip/references/issue-documents.md:8 |
| skill:skills/paperclip/references/issue-documents.md:update-or-resolve-an-unclear-write:47 | optional_agent_tool | skills/paperclip/references/issue-documents.md:47 |
| skill:skills/paperclip/references/issue-documents.md:update-or-resolve-an-unclear-write:49 | optional_agent_tool | skills/paperclip/references/issue-documents.md:49 |
| skill:skills/paperclip/references/issue-workspaces.md:issue-workspace-runtime-controls:1 | optional_agent_tool | skills/paperclip/references/issue-workspaces.md:1 |
| skill:skills/paperclip/references/issue-workspaces.md:discover-the-workspace:5 | optional_agent_tool | skills/paperclip/references/issue-workspaces.md:5 |
| skill:skills/paperclip/references/issue-workspaces.md:control-services:23 | optional_agent_tool | skills/paperclip/references/issue-workspaces.md:23 |
@@ -1181,9 +1181,9 @@
"expectedMockState": "operation_result"
},
{
"id": "skill:skills/paperclip/references/issue-documents.md:47",
"id": "skill:skills/paperclip/references/issue-documents.md:49",
"kind": "skill_heading",
"sourceAnchor": "skills/paperclip/references/issue-documents.md#L47:update-or-resolve-an-unclear-write",
"sourceAnchor": "skills/paperclip/references/issue-documents.md#L49:update-or-resolve-an-unclear-write",
"heading": "Update or resolve an unclear write",
"primaryDisposition": "control_plane_owned",
"semanticOperation": "runtime_reconciliation",
@@ -5,6 +5,6 @@ Generated by `scripts/generate-capability-contract.mjs`; do not edit generated f
- Skill/reference headings: 161
- Legacy MCP tools: 42
- Eval cases: 106 across 16 groups
- Deterministic content SHA-256: `62bb46560eae22b04c1a9fead8b5b5e6a372d3015b297325dc4f649924f945c8`
- Deterministic content SHA-256: `e577ca3ad6e6b045a7413ac11008013c8c12c2dc954f5a7876b86d96fbe017e8`
Every row has exactly one primary disposition, a source anchor, a semantic operation, and a mock-state expectation.
@@ -1965,9 +1965,9 @@
]
},
{
"id": "skill:skills/paperclip/references/issue-documents.md:update-or-resolve-an-unclear-write:47",
"id": "skill:skills/paperclip/references/issue-documents.md:update-or-resolve-an-unclear-write:49",
"sourceKind": "skill_heading",
"sourceAnchor": "skills/paperclip/references/issue-documents.md:47",
"sourceAnchor": "skills/paperclip/references/issue-documents.md:49",
"title": "Update or resolve an unclear write",
"expectedSemantics": "Skill guidance headed “Update or resolve an unclear write”.",
"primaryDisposition": "optional_agent_tool",
@@ -1976,7 +1976,7 @@
"control_plane_invariant"
],
"evidenceIds": [
"skill:skills/paperclip/references/issue-documents.md:47"
"skill:skills/paperclip/references/issue-documents.md:49"
]
},
{
@@ -36,13 +36,15 @@ Construct a clickable Markdown link from the current issue and successful write
receipt, then add it to the completion comment or response:
```javascript
const prefix = issue.identifier.split("-")[0];
const documentUrl = `/${prefix}/issues/${issue.identifier}#document-${saved.key}`;
const issuePath = issue.identifier
? `/${issue.identifier.split("-")[0]}/issues/${issue.identifier}`
: `/issues/${issue.id}`;
const documentUrl = `${issuePath}#document-${saved.key}`;
const comment = `Saved [Task report](${documentUrl}).`;
```
Use the returned key: a locked document can redirect an agent's write to a new
document.
document. Unnumbered issues use their ID; the board resolves their company.
## Update or resolve an unclear write
@@ -67,6 +67,20 @@ describe("explicit Paperclip document delivery", () => {
}) as string;
expect(gradeContextIntegrity({ ...scenario, checkpoints: [initial, final] }).every(row => row.passed)).toBe(true);
});
it.each([null, undefined])("the shipped recipe supports an unnumbered issue with identifier %s", identifier => {
const reference = readFileSync(new URL("../../skills/paperclip/references/issue-documents.md", import.meta.url), "utf8");
const recipe = reference.match(/```javascript\n([\s\S]*?)```/)?.[1];
expect(recipe).toBeDefined();
const comment = runInNewContext(`${recipe}\ncomment`, {
issue: { id: "849c6474-ab4e-4428-981a-0b9a0207fa9b", identifier },
saved: { key: "report-agent-redirected" },
}) as string;
const target = comment.match(/\]\(([^)]+)\)/)?.[1];
expect(target).toBeDefined();
const url = new URL(target!, "https://paperclip.example");
expect(url.pathname).toBe("/issues/849c6474-ab4e-4428-981a-0b9a0207fa9b");
expect(url.hash).toBe("#document-report-agent-redirected");
});
it("preserves the original ambiguous request and assigned output procedure", () => {
expect(contextIntegrityScenario("assigned-skill-explicit-invocation", "probe").prompt).toBe(
"Use the assigned Context integrity output skill for this task, then follow its instructions and finish the task. Do not create child tasks or unrelated deliverables.",
+1 -1
View File
@@ -43,7 +43,7 @@ export const stockHarnessGates = [
files: ["tests/runner-e2e/stock-harness-manifest.test.ts", "tests/runner-e2e/paperclip-document.test.ts", "tests/runner-e2e/stock-harness.test.ts", "tests/runner-e2e/stock-harness-checks.test.mjs",
"tests/runner-e2e/stock-harness-admission.test.ts", "tests/runner-e2e/stock-harness-digest.test.ts",
"tests/runner-e2e/select-rerun-artifacts.test.ts"],
required: ["requires generated capability manifests for the current skill sources", "the shipped recipe delivers the current", "rejects old SHA before providers", "allows toolchain paths and excludes every present or future credential",
required: ["requires generated capability manifests for the current skill sources", "the shipped recipe delivers the current", "the shipped recipe supports an unnumbered issue", "rejects old SHA before providers", "allows toolchain paths and excludes every present or future credential",
"changes when the evaluated server/src/onboarding-assets/default/AGENTS.md changes",
"changes when the evaluated packages/adapter-utils/src/server-utils.ts changes",
"changes when the evaluated packages/shared/src/connection-intent-guidance.ts changes",